FileSize函数的问题

时间:2014-07-24 08:44:08

标签: delphi

我正在尝试使用system.filesize函数来获取delphi中文件的大小,它适用于文件< 4GB但文件失败> 4GB。 所以我实现了自己的操作,将所需的文件作为文件流打开,并获得完美的流程化。

这是一个代码段

   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的文件的错误文件大小。

德尔福版:XE5

感谢。

3 个答案:

答案 0 :(得分:15)

System.FileSize是Pascal I / O函数,它对Pascal File变量进行操作。如果要获取path指定的文件大小,那么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;

答案 1 :(得分:2)

使用Google搜索关键字“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;

答案 2 :(得分:2)

您可以通过分配到我认为使下面的代码更有效的变体记录来避免位移。

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;

我可能只是使用了“case Boolean”,但是喜欢使用Pascal的强大功能来使代码更具描述性。