Получение размера файла в Delphi 2010 или новее?
В Delphi 2010 есть хороший набор новых функций доступа к файлам в IOUtils.pas
(особенно мне нравятся версии UTC связанных с датой функций). То, что я пропустил до сих пор, похоже на
TFile.GetSize (const Path : String)
Что такое Delphi 2010-way для получения размера файла? Должен ли я вернуться и использовать FindFirst для доступа к TSearchRec.FindData
?
Спасибо.
Ответы
Ответ 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;