delphi - FileSize,与这个程序有什么区别以及什么更好用?

标签 delphi delphi-xe2

关于获取文件的大小,我有这两个函数:

function GetFileSize1(const FileName: TFileName): Int64;
var
 iTmp: Int64;
 SearchRec: TSearchRec;
begin
  iTmp := -1;
  if FindFirst(FileName, faAnyFile, SearchRec) = 0 then
  begin
    iTmp := SearchRec.Size;
    System.SysUtils.FindClose(SearchRec);
  end;
  Result := iTmp;
end;

还有:

function GetFileSize2(const FileName: TFileName): Int64;
var
 FileStream: TFileStream;
begin
  FileStream := TFileStream.Create(FileName, fmOpenRead);
  try
    Result := FileStream.Size; 
  finally  
    FileStream.Free;
  end; 
end;

在实践中,它有什么区别?当然,两者都会返回相同的结果,但是什么更可靠、更快速、更安全呢?或者更好的是,首选用途是什么?第一还是第二? 非常感谢。

最佳答案

嗯,明显的区别是 GetFileSize2 打开文件,使用 CreateFile API 获取文件句柄。相反,GetFileSize1 则不会,因为它从文件元数据中读取大小。

所以我希望 GetFileSize1 表现更好。不过,对于许多应用程序来说,性能差异并不重要。更重要的是,在 GetFileSize1 会成功的情况下,GetFileSize2 可能会因共享冲突而失败。所以你真的不应该使用GetFileSize2

另请注意,您提供的两个函数在发生错误时的行为有所不同:GetFileSize1 返回 -1,而 GetFileSize2 引发异常。

我个人更喜欢这个版本:

function GetFileSize3(const FileName: string): Int64;
var
  fad: TWin32FileAttributeData;
begin
  if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @fad) then
    RaiseLastOSError;
  Int64Rec(Result).Lo := fad.nFileSizeLow;
  Int64Rec(Result).Hi := fad.nFileSizeHigh;
end;

或者,如果您希望在出现错误时返回 -1,您可以这样写:

function GetFileSize3(const FileName: string): Int64;
var
  fad: TWin32FileAttributeData;
begin
  if not GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @fad) then
    exit(-1);
  Int64Rec(Result).Lo := fad.nFileSizeLow;
  Int64Rec(Result).Hi := fad.nFileSizeHigh;
end;

感觉这比调用 FindFirstFile 更自然,但这可能只是个人喜好。 FindFirstFile 方法确实没有任何问题。尽管它不需要 iTmp 变量。你可以这样写得更清楚:

function GetFileSize1(const FileName: TFileName): Int64;
var
 SearchRec: TSearchRec;
begin
  if FindFirst(FileName, faAnyFile, SearchRec) = 0 then
  begin
    Result := SearchRec.Size;
    System.SysUtils.FindClose(SearchRec);
  end
  else
    Result := -1;
end;

更新: @CodeInChaos 对于不打开文件句柄的方法提出了很好的观点。这些方法可能会为硬链接(hard link)文件提供不准确的结果。

关于delphi - FileSize,与这个程序有什么区别以及什么更好用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13430927/

相关文章:

delphi - 如何保护Web服务免受拒绝服务攻击?

delphi - 派生的TClient数据集;定义始终运行的 OnAfterPost

delphi - 为什么 {$ifopt FINITEFLOAT ON} 无法编译?

macos - 我可以使用 Delphi XE2 (v16) 轻松编译适用于 Mac OS X 的现有 Delphi 应用程序吗?

delphi - 如何在Delphi调用堆栈窗口中隐藏 'non-user'堆栈帧?

德尔福XE2 : How to prevent the Alt key stealing focus?

macos - 使用BorderStyle bsNONE移动表格吗?

windows - Delphi 主题工具栏是否可以在其工具按钮之间设置分隔线?

delphi - 如何将空终止字符串转换为字符串?

delphi - 如何翻译 Firemonkey 的资源字符串?