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

StackOverflow https://stackoverflow.com/questions/1642220

  •  10-07-2019
  •  | 
  •  

Вопрос

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

TFile.GetSize (const Path : String)

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

Спасибо.

Это было полезно?

Решение

Я не уверен, существует ли способ "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() Получить файл() но для этого требуется дескриптор файла, а не просто имя файла, и аналогично GetCompressedFileSize() Получить сжатый файл() предположение, для этого требуется вызвать две переменные.И то, и другое GetFileSize() Получить файл() и GetCompressedFileSize() Получить сжатый файл() перегружайте их возвращаемое значение, поэтому тестирование на успешность и обеспечение достоверного результата просто немного более неудобно.

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

Другие советы

Использование устройства Indy:

uses IdGlobalProtocols;

function FileSizeByName(const AFilename: TIdFileName): Int64;

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

Я хотел бы упомянуть несколько Чистый Дельфи способами.Хотя я думаю, что Дельтики сделал наиболее быстрый ответ для Платформа Windows, но иногда вы хотите просто положиться на RTL , а также создать переносимый код , который работал бы в Delphi для macOS или в FreePascal/ Виртуальный Паскаль / что угодно.


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

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

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


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

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


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

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

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;

Это короткое решение, использующее 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;

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top