Delphi 文件大小函数的问题
我正在尝试使用system.filesize函数在delphi中获取文件的大小,对于小于4GB的文件,它可以正常工作,但是对于大于4GB的文件,它会失败。 因此,我实现了我自己的,它以文件流的形式打开所需的文件,并获得工作完美的streamsize 这里是一个片段Delphi 文件大小函数的问题,delphi,Delphi,我正在尝试使用system.filesize函数在delphi中获取文件的大小,对于小于4GB的文件,它可以正常工作,但是对于大于4GB的文件,它会失败。 因此,我实现了我自己的,它以文件流的形式打开所需的文件,并获得工作完美的streamsize 这里是一个片段 function GiveMeSize(PathtoFile : string): int64; var stream : TFileStream; size : int64; begin
function GiveMeSize(PathtoFile : string): int64;
var
stream : TFileStream;
size : int64;
begin
try
stream := TFileStream.Create(PathtoFile, fmOpenReadWrite or fmShareDenyNone);
size := stream.size;
except
showmessage('Unable to get FileSize');
end
finally
stream.free;
end;
但是我上面的函数的问题是,它打开文件,在处理大量文件时会产生一些开销。
是否有任何函数可以在不首先打开文件的情况下获得大于4GB的文件大小?
我在网上尝试了一些功能,但对于大于4GB的文件,它们往往会报告错误的文件大小
Delphi版本:XE5
谢谢。是一个Pascal I/O函数,可对Pascal文件
变量进行操作。如果您想获取路径指定的文件大小,那么使用System.FileSize
函数是错误的
更重要的是,您很可能不想仅仅为了获得文件的大小而打开文件。我获得的文件大小如下:
function FileSize(const FileName: string): Int64;
var
AttributeData: TWin32FileAttributeData;
begin
if GetFileAttributesEx(PChar(FileName), GetFileExInfoStandard, @AttributeData) then
begin
Int64Rec(Result).Lo := AttributeData.nFileSizeLow;
Int64Rec(Result).Hi := AttributeData.nFileSizeHigh;
end
else
Result := -1;
end;
通过谷歌搜索关键字“delphi get file size int64”可以为您提供大量示例
我用这个:
function GetSizeOfFile(const Filename: string): Int64;
var
sr : TSearchRec;
begin
if FindFirst(fileName, faAnyFile, sr ) <> 0 then
Exit(-1);
try
result := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + Int64(sr.FindData.nFileSizeLow);
finally
System.SysUtils.FindClose(sr) ;
end;
end;
函数GetSizeOfFile(const Filename:string):Int64;
变量
sr:TSearchRec;
开始
如果FindFirst(fileName,faAnyFile,sr)为0,则
出口(-1);
尝试
结果:=Int64(sr.FindData.nFileSizeHigh)shl Int64(32)+Int64(sr.FindData.nFileSizeLow);
最后
System.SysUtils.FindClose(sr);
结束;
结束;
您可以通过分配到变量记录中来避免位移位,我认为这会使下面的代码更有效
function GetSizeOfFile(const Filename: string): Int64;
type
TSizeType = (stDWORD, stInt64);
var
sizerec: packed record
case TSizeType of
stDWORD: (SizeLow: LongWord; SizeHigh: LongWord);
stInt64: (Size: Int64);
end;
sr : TSearchRec;
begin
if FindFirst(fileName, faAnyFile, sr ) <> 0 then
begin
Result := -1;
Exit;
end;
try
sizerec.SizeLow := sr.FindData.nFileSizeLow;
sizerec.SizeHigh := sr.FindData.nFileSizeHigh;
Result := sizerec.Size;
finally
SysUtils.FindClose(sr) ;
end;
end;
函数GetSizeOfFile(const Filename:string):Int64;
类型
TSizeType=(stDWORD,stInt64);
变量
压缩记录
case-tsizType的
stDWORD:(SizeLow:LongWord;SizeHigh:LongWord);
stInt64:(大小:Int64);
结束;
sr:TSearchRec;
开始
如果FindFirst(fileName,faAnyFile,sr)为0,则
开始
结果:=-1;
出口
结束;
尝试
sizerec.SizeLow:=sr.FindData.nFileSizeLow;
sizerec.SizeHigh:=sr.FindData.nFileSizeHigh;
结果:=sizerec.Size;
最后
SysUtils.FindClose(sr);
结束;
结束;
我本可以使用“case Boolean of”,但我喜欢使用Pascal的强大功能使代码更具描述性。不,上述函数的问题是它甚至无法编译。顺便说一句,你的分享模式很奇怪。很抱歉。刚刚在我的浏览器中大声说出了我脑海中的代码。:)但我希望你们明白我想指出的是什么?请不要发布假代码。请注意张贴真实代码。对不起,我目前不在我的开发电脑旁。注意:)这段代码有它的问题。例如,问问自己,当您将路径
'C:\Windows\System32\*.dll'
传递给它时会发生什么。对于使用FindFirstFile
进行枚举文件以外的操作,这一直是我的一个问题。@David,我有责任将一个文件名传递给该代码的使用者。但是同意您的观点,即FindFirst
应该用于枚举文件,而不是用于其他任何事情。@TLama这确实有点牵强。我认为,用户可以合理地预期不会向该函数传递通配符。但当有非常好的替代方案时,像这样的代码总是困扰着我。我怀疑早在那时,FindFirstFile
是读取属性的最快API,但微软在XP中通过在JCLFindFirstFile
中添加GetFileAttributesEx
@David来处理这一问题,它还用于获取文件大小(至少在我当前的JCL版本中是这样)。我从来没有为你们俩使用过GetFileAttributesEx
(XP+)so+1。一直在学习:)我从保存代码的上下文中复制了代码,以假设传递了一个有效的文件名。但你们当然是对的,我只是想分享一个例子,说明如何做到这一点,因为它不使用“FindFirst”的东西。