33

Delphi 2010 中有一组不错的新文件访问函数IOUtils.pas(我特别喜欢与日期相关的函数的 UTC 版本)。到目前为止我想念的是

TFile.GetSize (const Path : String)

Delphi 2010获取文件大小的方法是什么?我是否必须返回并使用 FindFirst 才能访问TSearchRec.FindData

谢谢。

4

6 回答 6

56

我不确定是否有“Delphi 2010”方式,但有一种不涉及 FindFirst 和所有 jazz 的 Windows 方式

我将该例程的 Delphi 转换拼凑在一起(并在此过程中对其进行了修改以处理 > 4GB 大小的文件,如果您需要的话)。

  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()都重载了它们的返回值,因此测试成功并确保有效结果只是有点尴尬。

GetFileSize Ex ()避免了处理 > 4GB 文件大小和检测有效结果的细节,但也需要文件 HANDLE,而不是名称,并且(至少从 Delphi 2009 开始,我还没有检查 2010)不是在 VCL 中为您声明的任何地方,您都必须提供自己的导入声明。

于 2009-10-29T08:48:17.253 回答
10

使用印地单位:

uses IdGlobalProtocols;

function FileSizeByName(const AFilename: TIdFileName): Int64;
于 2012-08-04T11:34:20.510 回答
4

您还可以使用 DSiWin32 中的DSiFileSize。适用于“所有”德尔福。它在内部调用 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 }
于 2009-10-29T15:40:44.093 回答
3

我想提几个纯德尔福方法。尽管我认为Deltics为Windows 平台提供了最高效的解决方案,但有时您只想依赖 RTL 并制作可在Delphi for MacOSFreePascal/Virtual Pascal/whatever中工作的可移植代码。


FileSizeTurbo Pascal 时代遗留下来 的功能。

上面的示例缺少“只读”模式设置。您需要打开 r/o 文件,例如 CD-ROM 介质上的文件或 ACL 设置为 r/o 的文件夹中的文件。在调用之前ReSet应该将零分配给FileMode全局变量。

它不适用于大小超过 2GB 的文件(可能对基数演员有负面影响 - 最高 4GB),但它是“开箱即用”的文件。


如果您曾经为 MS-DOS 进行过 ASM 编程,您可能会熟悉另一种方法。您Seek将指针指向第一个字节,然后指向最后一个字节,并检查差异。
我不能确切地说是哪个 Delphi 版本引入了这些,但我认为它已经在一些古老的版本中,比如 D5 或 D7,尽管这只是常识,我无法检查。
这将带您一个额外的 THandle 变量并try-finally阻止在获取大小后始终关闭句柄。

除了第一种方法之外,它还支持 int64。它也与 FreePascal 兼容,但有一些限制


您还可以创建和使用-typed对象TFileStream- 这是Delphi 1.0

作为旁注,这条途径当然与上述IOUtils单元集成在一起。

于 2012-11-01T06:10:18.340 回答
2

这是使用 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。

于 2013-07-18T12:12:05.970 回答
1
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;
于 2016-09-12T18:31:29.237 回答