FileSize,与此过程有何区别?什么是更好的用法? [英] FileSize, what difference from this procedure and what is better use?

查看:148
本文介绍了FileSize,与此过程有何区别?什么是更好的用法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于获取文件的大小,我有以下两个功能:

about get size of a file, i have this two functions:

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;

实际上,有什么区别?当然,两者都返回相同的结果,但是更贴近,更快,更安全的是什么?或者更好的是,什么是首选用途?第一还是第二?
非常感谢。

In practise, what is the difference of it? Both return same result of course but what is more affidable, more fast, more secure? Or better, what is preferible use? First or second? Thanks very much.

推荐答案

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

Well, the obvious difference is that GetFileSize2 opens the file, using the CreateFile API to obtain a file handle. In contrast, GetFileSize1 does not because it reads the size from the file meta data.

所以我希望 GetFileSize1 执行得更好。虽然,对于许多应用程序而言,性能差异并不重要。更重要的是,在 GetFileSize1 成功的情况下,由于共享冲突, GetFileSize2 可能失败。因此,您实际上不应该使用 GetFileSize2

So I would expect GetFileSize1 to perform better. Although, for many applications that performance difference would not matter. Much more significantly, GetFileSize2 can fail due to a sharing violation in situations that GetFileSize1 will succeed. So you really should not use GetFileSize2.

请注意,如果出现错误: GetFileSize1 返回-1,并且 GetFileSize2 引发异常。

Note also that the two functions you present behave differently in case of an error: GetFileSize1 returns -1, and GetFileSize2 raises an exception.

我个人更喜欢这个版本:

Personally I prefer this version:

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,则可以这样写:

Or, if you prefer to return -1 in case of error you would write it like this:

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 变量。您可以像这样更清楚地编写它:

Some how this feels more natural than calling FindFirstFile, but that's perhaps just personal preference. There's really nothing wrong with the FindFirstFile approach. Although it doesn't need that iTmp variable. You can write it more clearly like this:

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很好地指出了不采用的方法t打开文件句柄。这些方法可能会使硬链接文件的结果不准确。

Update: @CodeInChaos makes a good point about the approaches that don't open a file handle. These approaches can give inaccurate results for hard linked files.

这篇关于FileSize,与此过程有何区别?什么是更好的用法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆