Delphi 文件大小函数的问题

Delphi 文件大小函数的问题,delphi,Delphi,我正在尝试使用system.filesize函数在delphi中获取文件的大小,对于小于4GB的文件,它可以正常工作,但是对于大于4GB的文件,它会失败。 因此,我实现了我自己的,它以文件流的形式打开所需的文件,并获得工作完美的streamsize 这里是一个片段 function GiveMeSize(PathtoFile : string): int64; var stream : TFileStream; size : int64; begin

我正在尝试使用system.filesize函数在delphi中获取文件的大小,对于小于4GB的文件,它可以正常工作,但是对于大于4GB的文件,它会失败。 因此,我实现了我自己的,它以文件流的形式打开所需的文件,并获得工作完美的streamsize

这里是一个片段

   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中通过在JCL
FindFirstFile
中添加
GetFileAttributesEx
@David来处理这一问题,它还用于获取文件大小(至少在我当前的JCL版本中是这样)。我从来没有为你们俩使用过
GetFileAttributesEx
(XP+)so+1。一直在学习:)我从保存代码的上下文中复制了代码,以假设传递了一个有效的文件名。但你们当然是对的,我只是想分享一个例子,说明如何做到这一点,因为它不使用“FindFirst”的东西。