如何在 Delphi XE2 上以跨平台的方式获取文件大小

5

我有这个例程来查看文件大小:

(基于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;

然而,这会出现以下警告:
[DCC Warning] Funciones.pas(61): W1002 Symbol 'FindData' is specific to a platform

我想知道是否存在一种干净的跨平台方法来做到这一点。我检查了TFile类,但没有找到它...


2
让我沮丧的是,FindFirst 似乎是获取文件大小信息的方法。这是违反直觉的,而且甚至不总是准确的。 - David Heffernan
4个回答

5

在Delphi XE2中,TSearchRec.Size成员已经是Int64(不确定是从哪个版本开始更改的),并且使用来自Windows的TSearchRec.FindData字段的完整64位值进行填充,因此无需手动计算大小,例如:

{$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; 

这个问题在XE版本中也存在。如果这个问题一直存在于D4-D6时期,人们可能会保留ifdef结构,因为它也适用于非常旧的版本。但由于几乎没有人支持D7之前的版本,我认为现在是时候消灭这个问题了。 - Marco van de Voort
它在 Delphi 2006 中切换为 Int64。 - Zoë Peterson

4
你收到的警告是由于TSearchRec结构体中的FindData成员仅适用于Windows平台,但当你在不同于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}

@TLama,这并不能消除警告。 - Francesca
但是,@François,问题是是否有跨平台的解决方案(OP已经拥有),而不是如何抑制警告 ;) 但我喜欢你的方法(+1)。 - TLama
是的,也许可以使用更好的问题,我可以想到如何做。但意图是跨平台并消除警告。更确切地说,是使用本地的Delphi XE2方法来实现。 - mamcx

4

因为您已经检查过您正在运行的是Windows,所以可以安全地将“警告”本地删除,只保留编译器报告的“真正”的警告:

  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}

-1
TDirectory.GetLastWriteTime(path);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接