Xor-el
Xor-el

Reputation: 242

Issues With FileSize Function

I am trying to use the system.filesize function to get the size of a file in delphi, it works ok for files < 4GB but fails for files > 4GB. so i implemented my own that opens the required file as a filestream and gets the streamsize which works perfectly.

Here is a Snippet

   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;

but the problem with my above function is that it opens the file which incurs some overhead when processing a large number of files. is there any function that can get filesize of files > 4GB without opening the file first? I have tried some functions online but they tend to report wrong file size for files greater than 4GB.

Delphi Version : XE5

Thanks.

Upvotes: 3

Views: 3898

Answers (3)

Ian Hinson
Ian Hinson

Reputation: 21

You can avoid bit-shifting by assigning into a variant record which I think makes the code below more efficient.

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;

I could've just used "case Boolean of" but like to use the power of Pascal to make the code more descriptive.

Upvotes: 2

David Heffernan
David Heffernan

Reputation: 612934

System.FileSize is a Pascal I/O function that operates on Pascal File variables. If you want to get the size of a file specified by path, then System.FileSize is simply wrong function to use.

What's more, you quite likely don't want to open the file just to obtain its size. I obtain the file size like this:

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;

Upvotes: 20

Joe Meyer
Joe Meyer

Reputation: 448

Googling for the keywords "delphi get file size int64" gives you plenty of examples

I use this:

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;

Upvotes: 2

Related Questions