Подтвердить что ты не робот

Получение размера файла в Delphi 2010 или новее?

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

TFile.GetSize (const Path : String)

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

Спасибо.

4b9b3361

Ответ 1

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

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

  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() перегружают свое возвращаемое значение, поэтому тестирование на успех и обеспечение допустимого результата просто немного более неудобны.

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

Ответ 2

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

uses IdGlobalProtocols;

function FileSizeByName(const AFilename: TIdFileName): Int64;

Ответ 3

Вы также можете использовать 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 }

Ответ 4

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


Есть функция FileSize, оставшаяся от дней Turbo Pascal.

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

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


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

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


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

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

Ответ 5

Это короткое решение с использованием 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.

Ответ 6

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;