.NET Framework - Pasar de bytes a Megas y Gigas.

Asked By Sergitux on 12-Aug-08 03:08 AM
Buenas me gustar=EDa saber los megas o los gigas de un archivo lo
curioso que si son peque=F1os los datos me los los resuelvo bien. Pero
estado probando con un archivo de 120GB (123.256.660.992 bytes) y no
me da el resultado deseado me resuelve los datos en negativos y sin
sentido... "-1 en Gigas y -1237 Megas".

Dim SiZze As Long
Dim gb As Integer
Dim mg As Integer

SiZze =3D FileLen(Text1 & Text2)

gb =3D SiZze / 1073741824
mg =3D SiZze / 1048576

MsgBox "Gigas: " & gb & " | " & "Megas:" & mg

Muchas Gracias de antemano.
Sergio.-




Hernán replied on 11-Aug-08 07:52 AM
Prueba con doubles o currencys... Un long es de masiado chico (31 *
log10 = 9,33), el tipo almacena hasta 10 dígitos y vos necesitás 12.

--
Todo bien.
Hernán replied on 11-Aug-08 08:03 AM
Ok, no ví el FileLen(). No conozco esa función, pero si usas
GetFileSizeEx() obtienes, en un vector de 2 long, el tamaño del archivo.
Yo no sé si vb maneja el tipo long long.

--
Todo bien.
Sergitux replied on 15-Aug-08 08:31 PM
.

Tienes alg=FAn ejemplo?
Sergitux replied on 15-Aug-08 08:31 PM
Al final lo consegu=ED con la API. Os dejo el c=F3digo si un futuro
alguien lo necesita. Gracias

Private Const GENERIC_READ =3D &H80000000
Private Const FILE_SHARE_READ =3D &H1
Private Const OPEN_EXISTING =3D 3
Private Declare Function CreateFile Lib "kernel32" Alias
Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal
dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long,
ByVal hTemplateFile As Long) As Long
Private Declare Function GetFileSizeEx Lib "kernel32" (ByVal hFile As
Long, lpFileSize As Currency) As Boolean
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As
Long) As Long

Private Sub Form_Load()
Dim hFile As Long, nSize As Currency

hFile =3D CreateFile("c:\test.exe", _
GENERIC_READ, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, _
ByVal 0&, ByVal 0&)

GetFileSizeEx hFile, nSize

CloseHandle hFile

Dim hola As Currency
hola =3D Str$(nSize * 10000)
MsgBox "Megas: " & Int(hola / 1048576)
MsgBox "Gigas: " & Int(hola / 1073741824)
End
End Sub
Vin replied on 12-Aug-08 10:24 AM
Hola,
si quieres mantener compatibilidad con versiones antiguas de =
Windows, GetFileSizeEx no te serivir=EDa, deber=EDas entonces usar por =
ejemplo FindFirstFile la cual en caso de realizarse con =E9xito la =
llamada te rellena una estructura con informaci=F3n diversa del fichero, =
entre la que se encuentran los valores que buscas, por ejemplo:

'***************************
Public Function FileLenEx(ByVal Ruta As String) As Currency
Dim hFile   As Long
Dim WFD     As WIN32_FIND_DATA
=20
hFile =3D FindFirstFile(Ruta, WFD)
=20
If hFile <> -1 Then
Dim partes As LARGE_INTEGER
Dim Valor  As LARGE_INTEGER_CURRENCY
=20
partes.HighPart =3D WFD.nFileSizeHigh
partes.LowPart =3D WFD.nFileSizeLow

LSet Valor =3D partes
FileLenEx =3D Valor.Valor * CCur(10000)
=20
FindClose hFile
Else
'Error Err.LastDllError
End If
End Function
'***************************

El c=F3digo dentro del 'If' tambi=E9n lo podr=EDas sustituir por lo =
siguiente:
'**************
RtlMoveMemory ByVal VarPtr(FileLenEx), WFD.nFileSizeLow, 4
RtlMoveMemory ByVal VarPtr(FileLenEx) + 4, WFD.nFileSizeHigh, 4
FileLenEx =3D FileLenEx * CCur(10000)
FindClose hFile
'**************

Yo prefiero la primera, m=E1s c=F3digo pero m=E1s seguro.

Con las declaraciones siguientes, eliminando RtlMoveMemory o los =
LARGE_INTEGER seg=FAn lo que quisieras usar:

'--------------------------
Private Const MAX_PATH As Long =3D 260

Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

Private Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName As String * MAX_PATH
cAlternate As String * 14
End Type

Private Declare Function FindFirstFile Lib "kernel32.dll" Alias =
ByVal lpFileName As String, _
ByRef lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32.dll" ( _
ByVal hFindFile As Long) As Long

Private Type LARGE_INTEGER
LowPart     As Long
HighPart    As Long
End Type

Private Type LARGE_INTEGER_CURRENCY
Valor As Currency
End Type

Private Declare Sub RtlMoveMemory Lib "kernel32.dll" ( _
ByRef Destination As Any, _
ByRef Source As Any, _
ByVal Length As Long)
'--------------------------    =20



--=20
Saludos
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Respuestas precedentes en Google:
http://groups.google.com/group/microsoft.public.es.vb
( i ) Temperancia en el foro:
http://support.microsoft.com/default.aspx?scid=3Dfh;ES-ES;newsreglas
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Hernán replied on 12-Aug-08 10:44 AM
Vinchenzo vinç escribía:

[...]
[...]

Buenas noches Vinchenzo,

Poner el high arriba del low, ¡en qué cabeza cabe?

--
Todo bien.
Vin replied on 12-Aug-08 09:05 PM
Saludos Hern=E1n,
pues es la forma en que se rellena la estructura dentro de =
FindFirstFile, Microsoft lo quiere as=ED, y es como se definen las dos =
versiones en WinBase.h:

typedef struct _WIN32_FIND_DATAA {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
CHAR   cFileName[ MAX_PATH ];
CHAR   cAlternateFileName[ 14 ];
DWORD dwFileType;
DWORD dwCreatorType;
WORD  wFinderFlags;
} WIN32_FIND_DATAA, *PWIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;

typedef struct _WIN32_FIND_DATAW {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD dwReserved0;
DWORD dwReserved1;
WCHAR  cFileName[ MAX_PATH ];
WCHAR  cAlternateFileName[ 14 ];
DWORD dwFileType;
DWORD dwCreatorType;
WORD  wFinderFlags;
} WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;

typedef WIN32_FIND_DATAW WIN32_FIND_DATA;
typedef PWIN32_FIND_DATAW PWIN32_FIND_DATA;
typedef LPWIN32_FIND_DATAW LPWIN32_FIND_DATA;
typedef WIN32_FIND_DATAA WIN32_FIND_DATA;
typedef PWIN32_FIND_DATAA PWIN32_FIND_DATA;
typedef LPWIN32_FIND_DATAA LPWIN32_FIND_DATA;




--=20
Saludos
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Respuestas precedentes en Google:
http://groups.google.com/group/microsoft.public.es.vb
( i ) Temperancia en el foro:
http://support.microsoft.com/default.aspx?scid=3Dfh;ES-ES;newsreglas
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Vin replied on 12-Aug-08 09:11 PM
Pues, FileLen siempre devuelve =FAnicamente el low-order del =
tama=F1o del fichero, independientemente del tama=F1o, e =
independientemente del tama=F1o que ocupe en disco (en NTFS puedes tener =
un fichero de 4 GB que ocupe 4 KB en disco). Si queremos consultar el =
tama=F1o que ocupa en disco vamos a usar GetCompressedFileSize: =
LowPart=3DGetCompressedFileSize(Ruta, HighPart)

As=ED, FileLen devolver=EDa 0 si consultamos el tama=F1o de un =
fichero que ocupa 4GB (exactamente 4.294.967.296 bytes), aqu=ED el =
high-order es 1 y el low-order 0.



--=20
Saludos
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( ! ) Respuestas precedentes en Google:
http://groups.google.com/group/microsoft.public.es.vb
( i ) Temperancia en el foro:
http://support.microsoft.com/default.aspx?scid=3Dfh;ES-ES;newsreglas
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -