Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How get filesize in cross-platform way on delphi xe2

I have this rutine to know the filesize:

(Based on http://delphi.about.com/od/delphitips2008/qt/filesize.htm)

function FileSize(fileName : String) : Int64;
var
  sr : TSearchRec;
begin
  if FindFirst(fileName, faAnyFile, sr ) = 0 then
  {$IFDEF MSWINDOWS}
     result := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + Int64(sr.FindData.nFileSizeLow)
  {$ELSE}
     result := sr.Size
  {$ENDIF}
  else
     result := -1;

  FindClose(sr) ;
end;

However, this give this warning:

[DCC Warning] Funciones.pas(61): W1002 Symbol 'FindData' is specific to a platform

I wonder if exist a clean cross-platform way to do this. I check TFile class and not found it...

like image 683
mamcx Avatar asked Feb 03 '12 00:02

mamcx


3 Answers

In Delphi XE2, the TSearchRec.Size member is already an Int64 (not sure which version that changed in) and is filled in with the full 64-bit value from the TSearchRec.FindData fields on Windows, so there is no need to calculate the size manually, eg:

{$IFDEF VER230}
  {$DEFINE USE_TSEARCHREC_SIZE}
{$ELSE}
  {$IFNDEF MSWINDOWS} 
    {$DEFINE USE_TSEARCHREC_SIZE}
  {$ENDIF} 
{$ENDIF}

function FileSize(fileName : String) : Int64; 
var 
  sr : TSearchRec; 
begin 
  if FindFirst(fileName, faAnyFile, sr ) = 0 then 
  begin
    {$IFDEF USE_TSEARCHREC_SIZE}
    Result := sr.Size;
    {$ELSE}
    Result := (Int64(sr.FindData.nFileSizeHigh) shl 32) + sr.FindData.nFileSizeLow;
    {$ENDIF} 
    FindClose(sr); 
  end
  else 
     Result := -1; 
end; 
like image 151
Remy Lebeau Avatar answered Oct 23 '22 04:10

Remy Lebeau


The warning you are getting because the FindData member of the TSearchRec structure is specific to Windows platform, but you don't need to worry about it because in your code you are not accessing that member when you are on the platform different from Windows.

// condition if you are on the Windows platform
{$IFDEF MSWINDOWS}
  // here you can access the FindData member because you are
  // on Windows
  Result := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + 
    Int64(sr.FindData.nFileSizeLow);
{$ELSE}
  // here you can't use FindData member and you would even 
  // get the compiler error because the FindData member is 
  // Windows specific and you are now on different platform
{$ENDIF}
like image 33
TLama Avatar answered Oct 23 '22 02:10

TLama


Because you already check you are running on Windows, it is safe to remove locally the Warning to keep only "real" warnings reported by the compiler:

  if FindFirst(fileName, faAnyFile, sr ) = 0 then
  {$IFDEF MSWINDOWS}
    {$WARN SYMBOL_PLATFORM OFF}
     result := Int64(sr.FindData.nFileSizeHigh) shl Int64(32) + Int64(sr.FindData.nFileSizeLow)
    {$WARN SYMBOL_PLATFORM ON}
  {$ELSE}
like image 34
Francesca Avatar answered Oct 23 '22 03:10

Francesca