Pregunta

Delphi 2010 tiene un buen conjunto de nuevas funciones de acceso a archivos en IOUtils.pas (especialmente me gustan 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 y usar FindFirst para acceder a TSearchRec.FindData ?

Gracias.

¿Fue útil?

Solución

No estoy seguro de si hay un "Delphi 2010" manera, pero hay una forma de Windows que no involucra FindFirst y todo ese jazz .

Reuní 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 necesite).

  uses
    WinApi.Windows;

  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 un archivo HANDLE, no solo un nombre de archivo, y similar a la sugerencia GetCompressedFileSize () , esto requiere dos variables a 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 el meollo del manejo > Tamaño de archivo de 4GB y detección de resultados válidos, pero también requiere un MANGO de archivo, en lugar de un nombre, y (a partir de Delphi 2009 al menos, no he verificado 2010) no está declarado para usted en el VCL en ninguna parte, habría para proporcionar su propia declaración de importación.

Otros consejos

Uso de una unidad Indy:

uses IdGlobalProtocols;

function FileSizeByName(const AFilename: TIdFileName): Int64;

También puede usar DSiFileSize desde DSiWin32 . Funciona en " all " 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 }

Me gustaría mencionar algunas formas de Pure Delphi . Aunque creo que Deltics fue la respuesta más eficaz en cuanto a velocidad para la plataforma Windows , a veces solo debes confiar en RTL y también hacer un código portátil que funcione en Delphi para MacOS o en FreePascal / Virtual Pascal / lo que sea .


Queda la función FileSize de los días de Turbo Pascal.

La muestra anterior carece de "solo lectura" ajuste de modo. Necesitaría eso para abrir un archivo r / o como uno en un CD-ROM o en una carpeta con ACL configuradas en r / o. Antes de llamar a ReSet , debe haber cero asignado a FileMode global var.

No funcionaría en archivos con un tamaño superior a 2 GB (tal vez con un negativo a la emisión cardinal, hasta 4 GB) pero está "listo para usar" uno.


Hay un enfoque más, que puede ser familiar si alguna vez realizó la programación de ASM para MS-DOS. Seeker apunta el archivo al primer byte, luego al último byte y comprueba 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 una variable THandle adicional y un bloque try-finally para cerrar siempre el controlador después de obtener el tamaño.

Aparte del primer enfoque, esto es compatible con int64. También es compatible con FreePascal, aunque con algunas limitaciones


También puede crear y usar el objeto TFileStream , que fue el principal , oficialmente bendito avenida para operaciones de archivos desde Delphi 1.0

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;

Esta es una solución corta usando 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 está disponible solo desde XE2.

scroll top