获取文件大小>然后获得总大小?

时间:2011-11-26 18:21:45

标签: delphi math filesize

这应该很容易,但我似乎无法正确行事,因为我似乎在混淆自己并转换为字符串,整数和浮点数等等。

基本上,我在一列中使用FileNames填充TListView,在另一列中将File Size返回到相应的FileName。我正在使用here中的一个相当简洁的函数,它看起来像这样:

function FileSizeStr ( filename: string ): string;
const
//   K = Int64(1000);     // Comment out this line OR
  K = Int64(1024);     // Comment out this line
  M = K * K;
  G = K * M;
  T = K * G;
var
  size: Int64;
  handle: integer;
begin
  handle := FileOpen(filename, fmOpenRead);
  if handle = -1 then
    result := 'Unable to open file ' + filename
  else try
    size := FileSeek ( handle, Int64(0), 2 );
    if size < K then result := Format ( '%d bytes', [size] )
    else if size < M then result := Format ( '%f KB', [size / K] )
    else if size < G then result := Format ( '%f MB', [size / M] )
    else if size < T then result := Format ( '%f GB', [size / G] )
    else result := Format ( '%f TB', [size / T] );
  finally
    FileClose ( handle );
  end;
end;

返回如下值:235.40 KB

因此,使用上述内容,我的TListView可能会像这样填充:

enter image description here

现在在Label Data Size中,我想返回Listview中文件的总大小,所以在这个例子中,Size列中的值需要加起来才能返回Total Size,如:< / p>

1.28 MB + 313.90 KB + 541.62 KB + 270.96 KB

显然它不能像那样添加,因为值包含小数点,某些值可能在Kb中,而其他在Mb中等等。这是我的问题,我想不出一个简单的解决方案来添加(get)文件的总大小,然后以相同的格式化字符串返回它。

我非常感谢有关如何处理这类数据的一些见解或提示,我只是无休止地将自己与不同的转换等混淆,并且不确定以哪种方式执行此操作。

非常感谢提前:)

更新1

根据Marc B的建议,我将功能改为以下似乎有效:

var
  iFileSize: Int64;

implementation

function GetSizeOfFile(FileName: string): Int64;
var
  Handle: Integer;
begin
  Handle := FileOpen(FileName, fmOpenRead);

  if Handle = -1 then
    MessageDlg('Unable to open file ' + FileName, mtError, [mbOk], 0)
  else try
    iFileSize := iFileSize + FileSeek(Handle, Int64(0), 2);
  finally
    FileClose(Handle);
  end;

  Result := iFileSize;
end;

function FormatFileSize(AValue: Int64): string;
const
  K = Int64(1024);
  M = K * K;
  G = K * M;
  T = K * G;
begin
  if AValue < K then Result := Format ( '%d bytes', [AValue] )
  else if AValue < M then Result := Format ( '%f KB', [AValue / K] )
  else if AValue < G then Result := Format ( '%f MB', [AValue / M] )
  else if AValue < T then Result := Format ( '%f GB', [AValue / G] )
  else Result := Format ( '%f TB', [AValue / T] );
end;

如果他们需要,它可能对其他人有用:)

更新2

此外,请参阅Ken White发布的答案,该答案提供了更有价值的信息,以及GetSizeOfFile功能的更新更新,效果很好:

enter image description here

2 个答案:

答案 0 :(得分:6)

将“获取文件信息”与“格式化字符串”分隔为两个单独的函数。文件信息函数获取文件大小并将其添加到运行总计中,然后调用格式化函数将简单整数转换为“nice”字符串。

答案 1 :(得分:2)

最简单的方法是更改​​函数以返回文件大小,并使用单独的函数格式化结果。

我知道您已经接受了答案,但您发布的更新代码存在一些问题(一个也是原始版本)。

首先,获取文件大小的方法非常慢,特别是如果您要使用它来列出大量文件。您实际上是打开文件,将文件指针移动到文件末尾以获取大小,然后关闭文件。此外,如果文件由另一个应用程序专门打开,则可能会失败。

其次,您的新版GetSizeOfFile出现逻辑错误。您每次都会添加全局累计值(这是您想要的),但您也会根据您发布的示例图像返回您不想要的新全局值。

以下是适用于您的GetSizeOfFile的替代品以及样本使用:

function GetSizeOfFile( const FileName: String ): Int64;
var
  Rec : TSearchRec;
begin
  Result := 0;
  if (FindFirst(FileName, faAnyFile, Rec) = 0) then
  begin
    Result := Rec.Size;
    FindClose(Rec);
  end;
end;

样品使用:

var
  FileSize: Int64;
  FileSizeString: string;
begin
  { Whatever code  }
  FileSize := GetSizeOfFile(SomeFileName);
  iFileSize := iFileSize + NewSize;
  FileSizeString := FormatFileSize(NewSize);

  { Add your file to your ListView.}
end;