Получить размер файла в Delphi 2010 или более поздней версии? - PullRequest
28 голосов
/ 29 октября 2009

Delphi 2010 имеет замечательный набор новых функций доступа к файлам в IOUtils.pas (мне особенно нравятся версии функций, связанных с датами, в формате UTC). То, что я до сих пор скучаю, это что-то вроде

TFile.GetSize (const Path : String)

Что такое Delphi 2010-способ получения размера файла? Должен ли я вернуться и использовать FindFirst для доступа к TSearchRec.FindData?

Спасибо.

Ответы [ 6 ]

48 голосов
/ 29 октября 2009

Я не уверен, есть ли способ «Delphi 2010», но есть способ Windows, который не включает FindFirst и весь этот джаз .

Я собрал это преобразование Delphi этой подпрограммы (и в процессе изменил ее для обработки> файлов размером 4 ГБ, если вам это нужно).

  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;

На самом деле вы можете просто использовать GetFileSize () , но для этого требуется файл HANDLE, а не просто имя файла, и аналогично предложению GetCompressedFileSize () , для этого нужны две переменные вызов. И GetFileSize () , и GetCompressedFileSize () перезагружают свое возвращаемое значение, поэтому проверка на успешность и обеспечение правильного результата немного неудобнее.

GetFileSize Ex () позволяет избежать тщательной обработки файлов размером> 4 ГБ и определения допустимых результатов, но также требует наличия файла HANDLE, а не имени, и (по состоянию на Delphi 2009, по крайней мере, я не проверял 2010) нигде не объявлен для вас в VCL, вам придется предоставить собственную декларацию импорта.

7 голосов
/ 04 августа 2012

Использование блока Indy:

uses IdGlobalProtocols;

function FileSizeByName(const AFilename: TIdFileName): Int64;
4 голосов
/ 29 октября 2009

Вы также можете использовать DSiFileSize от DSiWin32 . Работает во «всем» Delphis. Внутренне он вызывает CreateFile и 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 }
3 голосов
/ 01 ноября 2012

Я хотел бы упомянуть несколько Чистых Delphi способов. Хотя я думаю, Deltics дал наиболее эффективный ответ для платформы Windows , но иногда хочется просто полагаться на RTL и создавать переносимый код, который будет работать в Delphi для MacOS или в FreePascal / Virtual Pascal / независимо от того, .


От дней Турбо Паскаля осталась функция FileSize.

В приведенном выше примере отсутствует настройка режима «только для чтения». Вам потребуется, чтобы открыть файл r / o, например файл, на носителе CD-ROM или в папке с ACL, установленными в r / o. Перед вызовом ReSet должен быть назначен ноль для FileMode global var.

Он не будет работать с файлами размером более 2 ГБ (может быть, с отрицательным до кардинального приведения - до 4 ГБ), но "из коробки".


Существует еще один подход, который вам может быть знаком, если вы когда-либо занимались программированием ASM для MS-DOS. Вы Seek указываете на первый байт, затем на последний байт и проверяете разницу.
Я не могу точно сказать, какая версия Delphi представила их, но я думаю, что это уже было в какой-то древней версии, такой как D5 или D7, хотя это просто здравый смысл, и я не могу это проверить.
Для этого потребуется дополнительная переменная THandle и блок try-finally, чтобы всегда закрывать дескриптор после получения размера.

Помимо 1-го подхода, он поддерживает int64. Он также совместим с FreePascal, но с некоторыми ограничениями


Вы также можете создавать и использовать TFileStream типизированный объект - который был основным , официально благословенным каналом для файловых операций , начиная с Delphi 1.0

Как примечание, этот проспект, конечно, интегрирован с вышеупомянутым IOUtils блоком.

2 голосов
/ 18 июля 2013

Это короткое решение с использованием FileSize, которое выполняет работу:

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;

Из того, что я знаю, FileSize доступен только из XE2.

1 голос
/ 12 сентября 2016
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;
...