Obtener el tamaño de un archivo en Delphi 2010 o posterior?
file delphi-2010 (6)
Delphi 2010 tiene un buen conjunto de nuevas funciones de acceso a archivos en IOUtils.pas
(me gustan especialmente las versiones UTC de las funciones relacionadas con la fecha). Lo que extraño hasta ahora es algo así como
TFile.GetSize (const Path : String)
¿Cuál es la forma Delphi 2010 para obtener el tamaño de un archivo? ¿Tengo que volver atrás y usar FindFirst para acceder a TSearchRec.FindData
?
Gracias.
Esta es una solución corta con FileSize que hace el trabajo:
function GetFileSize(p_sFilePath : string) : Int64;
var
oFile : file of Byte;
begin
Result := -1;
AssignFile(oFile, p_sFilePath);
try
Reset(oFile);
Result := FileSize(oFile);
finally
CloseFile(oFile);
end;
end;
Por lo que sé, FileSize solo está disponible para XE2.
Me gustaría mencionar algunas formas Pure Delphi . Aunque creo que Deltics hizo una respuesta más rápida para la plataforma de Windows , sin embargo, a veces solo quieres confiar en RTL y también crear un código portátil que funcione en Delphi para MacOS o en FreePascal / Virtual Pascal / lo que sea .
Hay FileSize
función FileSize
que queda de los días de Turbo Pascal.
- http://turbopascal.org/system-functions-filepos-and-filesize
- http://docwiki.embarcadero.com/CodeExamples/XE2/en/SystemFileSize_(Delphi)
- http://docwiki.embarcadero.com/Libraries/XE2/en/System.FileSize
El ejemplo anterior carece de la configuración del modo "solo lectura". Necesitará que abra el archivo r / o como uno en medios CD-ROM o en una carpeta con ACL configuradas en r / o. Antes de llamar a ReSet
, debe haber cero asignado a la FileMode
global FileMode
.
No funcionaría en archivos con un tamaño superior a 2 GB (tal vez con conversión negativa a cardinal: hasta 4 GB), pero está "fuera de la caja".
Hay un enfoque más, que puede estar familiarizado si alguna vez hizo la programación de ASM para MS-DOS. Seek
el puntero de archivo en el primer byte, luego en el último byte y verifica la diferencia.
No puedo decir exactamente qué versión de Delphi introdujo esos, pero creo que ya estaba en alguna versión antigua como D5 o D7, aunque eso es solo sentido común y no puedo verificarlo.
Eso te llevaría a una variable adicional de Thandle y try-finally
bloquear para cerrar siempre el mango después de obtener el tamaño.
- Muestra de obtener longitud y tal
- http://docwiki.embarcadero.com/Libraries/XE2/en/System.SysUtils.FileOpen
- http://docwiki.embarcadero.com/Libraries/XE2/en/System.SysUtils.FileSeek
Aparte del primer enfoque, este es int64-capable. También es compatible con FreePascal, aunque con algunas limitaciones
También puede crear y usar el objeto TFileStream
TFileStream, que fue la avenida principal y oficialmente bendecida para las operaciones de archivos desde Delphi 1.0
- http://www.freepascal.org/docs-html/rtl/classes/tfilestream.create.html
- http://www.freepascal.org/docs-html/rtl/classes/tstream.size.html
- http://docwiki.embarcadero.com/Libraries/XE2/en/System.Classes.TFileStream.Create
- http://docwiki.embarcadero.com/Libraries/XE2/en/System.Classes.TStream.Size
Como nota al margen, esta avenida está, por supuesto, integrada con la unidad IOUtils
mencionada IOUtils
.
No estoy seguro de si hay una forma de "Delphi 2010", pero hay una forma de Windows que no incluye FindFirst y todo ese jazz .
Lancé esta conversión de Delphi de esa rutina (y en el proceso la modifiqué para manejar archivos de tamaño 4GB, en caso de que lo necesitaras).
function FileSize(const aFilename: String): Int64;
var
info: TWin32FileAttributeData;
begin
result := -1;
if NOT GetFileAttributesEx(PWideChar(aFileName), GetFileExInfoStandard, @info) then
EXIT;
result := Int64(info.nFileSizeLow) or Int64(info.nFileSizeHigh shl 32);
end;
En realidad, podría usar GetFileSize (), pero esto requiere una HANDLE de archivo, no solo un nombre de archivo, y similar a la sugerencia GetCompressedFileSize () , esto requiere dos variables para llamar. Tanto GetFileSize () como GetCompressedFileSize () sobrecargan su valor de retorno, por lo que probar el éxito y garantizar un resultado válido es un poco más incómodo.
GetFileSize Ex () evita los detalles de manipulación de archivos de tamaño> 4GB y la detección de resultados válidos, pero también requiere un archivo HANDLE, en lugar de un nombre, y (a partir de Delphi 2009 al menos, no he marcado 2010) no es declarado para usted en el VCL en cualquier lugar, deberá proporcionar su propia declaración de importación.
También puede usar DSiFileSize desde DSiWin32 . Funciona en "todos" Delphis. Internamente llama a CreateFile y GetFileSize.
function DSiFileSize(const fileName: string): int64;
var
fHandle: DWORD;
begin
fHandle := CreateFile(PChar(fileName), 0, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if fHandle = INVALID_HANDLE_VALUE then
Result := -1
else try
Int64Rec(Result).Lo := GetFileSize(fHandle, @Int64Rec(Result).Hi);
finally CloseHandle(fHandle); end;
end; { DSiFileSize }
Usando una unidad Indy:
uses IdGlobalProtocols;
function FileSizeByName(const AFilename: TIdFileName): Int64;
uses
System.Classes, System.IOUtils;
function GetFileSize(const FileName : string) : Int64;
var
Reader: TFileStream;
begin
Reader := TFile.OpenRead(FileName);
try
result := Reader.Size;
finally
Reader.Free;
end;
end;