嗯,明显的区别就是GetFileSize2
打开文件,使用CreateFile
API获取文件句柄。相反,GetFileSize1
不会因为它从文件元数据中读取大小。
所以我希望GetFileSize1
表现更好。虽然,对于许多应用程序而言,性能差异并不重要。更重要的是,在将成功GetFileSize2
的情况下,可能会由于共享冲突而失败。GetFileSize1
所以你真的不应该使用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;
有些感觉这比 call 更自然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 很好地说明了不打开文件句柄的方法。这些方法可能会为硬链接文件提供不准确的结果。