Получение размера файла в Delphi 2010 или более поздней версии?
-
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.
- http://turbopascal.org/system-functions-filepos-and-filesize
- http://docwiki.embarcadero.com/CodeExamples/XE2/en/SystemFileSize_ (Дельфи)
- http://docwiki.embarcadero.com/Libraries/XE2/en/System .Размер файла
В приведенном выше примере отсутствует настройка режима "только для чтения".Это потребуется для открытия файла r / o, например, на компакт-диске или в папке с ACL, установленным в r / o.Перед вызовом ReSet
там должен быть ноль , присвоенный FileMode
глобальный var.
Это не будет работать с файлами размером более 2 ГБ (возможно, с отрицательным приведением к кардинальному - до 4 ГБ), но это "из коробки".
Существует еще один подход, который вам, возможно, знаком, если вы когда-либо занимались ASM-программированием для MS-DOS.Ты Seek
укажите указатель на 1-й байт, затем на последний байт и проверьте разницу.
Я не могу точно сказать, в какой версии Delphi они были представлены, но я думаю, что это уже было в какой-то древней версии, такой как D5 или D7, хотя это просто здравый смысл, и я не могу это проверить.
Это потребовало бы от вас дополнительной переменной THandle и try-finally
заблокируйте, чтобы всегда закрывать дескриптор после получения размера.
- Пример получения длины и тому подобное
- http://docwiki.embarcadero.com/Libraries/XE2/en/System .Системные файлы.Открыть файл
- http://docwiki.embarcadero.com/Libraries/XE2/en/System .Системные файлы.Поиск файлов
Помимо 1-го подхода, это поддерживает int64.Он также совместим с FreePascal, хотя и с некоторыми ограничениями
Вы также можете создавать и использовать TFileStream
-типизированный объект - который был первичный, официально благословленный путь для файловых операций с тех пор как Delphi 1.0
- http://www.freepascal.org/docs-html/rtl/classes/tfilestream.create.html
- http://www.freepascal.org/docs-html/rtl/classes/tstream.size.html
- http://docwiki.embarcadero.com/Libraries/XE2/en/System .Классы.TFileStream.Создать
- http://docwiki.embarcadero.com/Libraries/XE2/en/System .Классы.TStream.Размер
В качестве дополнительного примечания, этот проспект, конечно же, интегрирован с вышеупомянутыми 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.