Получение размеров файла> А затем получение общего размера? - PullRequest
4 голосов
/ 26 ноября 2011

Это должно быть легко, но я, кажется, не могу понять это правильно, потому что я, кажется, путаю себя и преобразовываю в и из строк, целых чисел и чисел с плавающей точкой и еще много чего.

По сути, я заполняю TListView с помощьюFileNames в одном столбце и в другом столбце, возвращая размер файла соответствующему FileName.Я использую довольно аккуратную функцию, найденную из здесь , которая выглядит следующим образом:

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 КБ

Так что с выше,мой TListView может быть заполнен следующим образом:

enter image description here

Теперь в размере данных метки я хотел бы вернуть общий размер файлов в представлении списка, поэтому в этом примерезначения из столбца «Размер» необходимо сложить, чтобы получить общий размер, например:

1,28 МБ + 313,90 КБ + 541,62 КБ + 270,96 КБ

Очевидно, что его нельзя добавить точно так же, какчто, поскольку значения содержат десятичные точки, некоторые значения могут быть в килобайтах, а другие в мегабайтах и ​​т. д. Это моя проблема, я не могу придумать простого решения добавить (получить) общий размер файлов, а затем вернуть егов той же отформатированной строке, как показано.

Я был бы очень признателен за некоторые советы или подсказки, как работать с такого рода данными, я просто бесконечно путаю себя с различными конверсиями и т. д. и не совсем уверенкакой способ сделать это.

Большое спасибо заранее:)

ОБНОВЛЕНИЕ 1

Следуя совету Марка Б, я изменил функцию наследующее, что, кажется, работает:

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

Дополнительносм. ответ Кена Уайта, который предоставляет более ценную информацию, и более чистое обновление функции GetSizeOfFile, которая прекрасно работает:

enter image description here

Ответы [ 2 ]

6 голосов
/ 26 ноября 2011

Разделите «получить информацию о файле» и «отформатируйте строку размера» на две отдельные функции.Функция информации о файле извлекает размер файла и добавляет его к итоговой сумме, затем вызывает функцию форматирования для преобразования простого целого числа в строку «nice».

2 голосов
/ 27 ноября 2011

Самый простой способ - изменить свою функцию, чтобы она возвращала размер файла, и использовать отдельную функцию для форматирования результатов.

Я знаю, что вы уже приняли ответ, но у обновленного кода, который вы разместили, есть пара проблем (одна тоже была в оригинальной версии).

Во-первых, ваш метод получения размера файла очень медленный, особенно если вы собираетесь использовать его для отображения большого количества файлов. Вы фактически открываете файл, перемещаете указатель файла в конец файла, чтобы получить размер, а затем закрываете файл. Также может произойти сбой, если файл открыт исключительно другим приложением.

Во-вторых, ваша новая версия 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;
...