【问题标题】:How get filesize in cross-platform way on delphi xe2如何在delphi xe2上以跨平台方式获取文件大小
【发布时间】:2012-02-03 00:56:09
【问题描述】:

我有这个规则来了解文件大小:

(基于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 类并没有找到它...

【问题讨论】:

  • 令我沮丧的是 FindFirst 似乎是获取文件大小信息的方式。这是反直觉的,甚至并不总是准确的。

标签: delphi cross-platform compiler-warnings filesize


【解决方案1】:

在 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 之前的版本,我认为是时候杀死野兽了。
  • 它在 Delphi 2006 中切换到 Int64。
【解决方案2】:

您收到警告是因为 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,这不会删除警告。
  • 但是@François,问题是是否有跨平台解决方案(OP 已经有),而不是如何抑制警告;)但我喜欢你的方式(+1ed)
  • 是的,也许可以用一个更好的问题,我能想到怎么做。但目的是跨平台并删除警告。更准确地说,是一种原生的 delphi xe2 方法。
【解决方案3】:

因为您已经检查您是否在 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}

【讨论】:

    【解决方案4】:
    TDirectory.GetLastWriteTime(path);
    

    【讨论】:

      猜你喜欢
      • 2013-10-05
      • 2011-12-24
      • 2012-01-28
      • 2018-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-28
      相关资源
      最近更新 更多