Delphi 获取文件大小>;然后得到总尺寸?

Delphi 获取文件大小>;然后得到总尺寸?,delphi,math,filesize,Delphi,Math,Filesize,这应该很容易,但我似乎无法正确地理解它,因为我似乎混淆了自己,并在字符串、整数、浮点等之间进行转换 基本上,我在一列中用文件名填充TListView,在另一列中将文件大小返回到相应的文件名。我使用的是从中找到的一个相当简洁的函数,如下所示: function FileSizeStr ( filename: string ): string; const // K = Int64(1000); // Comment out this line OR K = Int64(1024);

这应该很容易,但我似乎无法正确地理解它,因为我似乎混淆了自己,并在字符串、整数、浮点等之间进行转换

基本上,我在一列中用文件名填充TListView,在另一列中将文件大小返回到相应的文件名。我使用的是从中找到的一个相当简洁的函数,如下所示:

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;
函数filesizest(文件名:string):string;
常数
//K=Int64(1000);//注释掉这行或
K=Int64(1024);//把这行注释掉
M=K*K;
G=K*M;
T=K*G;
变量
尺寸:Int64;
句柄:整数;
开始
句柄:=FileOpen(文件名,fmOpenRead);
如果handle=-1,则
结果:=“无法打开文件”+文件名
否则试试
大小:=FileSeek(句柄,Int64(0),2);
如果大小
这将返回值,例如:235.40 KB

因此,使用上述方法,我的TListView可能会按如下方式填充:

现在在标签数据大小中,我想返回Listview中文件的总大小,因此在本例中,大小列中的值需要相加才能返回总大小,类似于:

1.28MB+313.90KB+541.62KB+270.96KB

显然,不能像这样添加,因为这些值包含小数点,一些值可能以Kb为单位,另一些值以Mb为单位。这是我的问题,我想不出一个简单的解决方案来添加(获取)文件的总大小,然后以如图所示的格式字符串返回

我真的很想知道如何处理这类数据的一些见解或技巧,我只是不断地将自己与不同的转换混淆在一起,而不是真的确定用哪种方式来处理

非常感谢:)

更新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;
var
iFileSize:Int64;
实施
函数GetSizeOfFile(文件名:string):Int64;
变量
句柄:整数;
开始
句柄:=FileOpen(文件名,fmOpenRead);
如果Handle=-1,则
MessageDlg('无法打开文件“+文件名、mtError、[mbOk],0)
否则试试
iFileSize:=iFileSize+FileSeek(句柄,Int64(0),2);
最后
文件关闭(句柄);
结束;
结果:=iFileSize;
结束;
函数FormatFileSize(AValue:Int64):字符串;
常数
K=Int64(1024);
M=K*K;
G=K*M;
T=K*G;
开始
如果AValue
如果其他人需要它,它可能会对他们有用:)

更新2

此外,请参阅Ken White发布的答案,该答案提供了更多有价值的信息,以及GetSizeOfFile函数的更清晰更新,该更新非常有效:


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

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

我知道你已经接受了答案,但是你发布的更新代码有几个问题(其中一个也是原始版本)

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

其次,新版本的
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;
样本使用:

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;

一些如此简单的事情,我不知道为什么我从来没有想过,而不是不断尝试转换的价值观,因为我总是做的事情比需要更困难!让我试试这个方法。发布了一个关于问题文件大小部分的单独答案和一些代码。非常感谢Ken提供了我从中了解到的额外信息,我现在从您所说的关于原始代码缺陷的内容中了解了更多。