7 Stimmen

Delphi-Funktion zur Anzeige der Byte-Anzahl wie in Windows

Das ist ganz einfach (denke ich).

Gibt es eine systemeigene Funktion oder eine Funktion, die jemand erstellt hat, die von Delphi aus aufgerufen werden kann und die eine Anzahl von Bytes (z. B. eine Dateigröße) anzeigt, so wie es Windows im Feld Eigenschaften einer Datei anzeigt?

So zeigt z. B. das Windows-Eigenschaftsfeld verschiedene Größen an:

539 bytes (539 bytes)
35.1 KB (35,974 bytes)
317 MB (332,531,365 bytes)
2.07 GB (2,224,617,077 bytes)

Die Anzeige ist intelligent bei der Verwendung von Bytes, KB, MB oder GB und zeigt nur 3 signifikante Ziffern für KB, MB und GB an. Anschließend wird die genaue Anzahl der Bytes in Klammern angezeigt, wobei die Tausender durch Kommas getrennt werden. Es ist eine sehr schöne, gut durchdachte Anzeige.

Kennt jemand eine solche Funktion?


Edit: Ich bin sehr überrascht, dass es dafür keine Funktion gibt.

Vielen Dank für Ihre hilfreichen Ideen. Ich habe mir das hier ausgedacht, das zu funktionieren scheint:

function BytesToDisplay(A:int64): string;
var
  A1, A2, A3: double;
begin
  A1 := A / 1024;
  A2 := A1 / 1024;
  A3 := A2 / 1024;
  if A1 < 1 then Result := floattostrf(A, ffNumber, 15, 0) + ' bytes'
  else if A1 < 10 then Result := floattostrf(A1, ffNumber, 15, 2) + ' KB'
  else if A1 < 100 then Result := floattostrf(A1, ffNumber, 15, 1) + ' KB'
  else if A2 < 1 then Result := floattostrf(A1, ffNumber, 15, 0) + ' KB'
  else if A2 < 10 then Result := floattostrf(A2, ffNumber, 15, 2) + ' MB'
  else if A2 < 100 then Result := floattostrf(A2, ffNumber, 15, 1) + ' MB'
  else if A3 < 1 then Result := floattostrf(A2, ffNumber, 15, 0) + ' MB'
  else if A3 < 10 then Result := floattostrf(A3, ffNumber, 15, 2) + ' GB'
  else if A3 < 100 then Result := floattostrf(A3, ffNumber, 15, 1) + ' GB'
  else Result := floattostrf(A3, ffNumber, 15, 0) + ' GB';
  Result := Result + ' (' + floattostrf(A, ffNumber, 15, 0) + ' bytes)';
end;

Das ist wahrscheinlich gut genug, aber gibt es etwas Besseres?

12voto

Rob Kennedy Punkte 158781

Siehe die folgenden Funktionen, die alle in der shlwapi Bibliothek .

Mit jeder dieser Optionen erhalten Sie den ersten Teil des gewünschten Anzeigeformats. Prüfen Sie die Dokumentation oder schreiben Sie Ihre eigenen Tests, um zu bestätigen, dass sie die von Ihnen erwarteten Umrechnungen liefern, ob ein Megabyte aus 1000 oder 1024 Kilobytes besteht. Für den zweiten Teil Ihres Anzeigeformats können Sie mit den Antworten auf eine andere Stack Overflow-Frage beginnen:

Aber vielleicht ist diese Frage der falsche Weg, denn alle Vorschläge, die hier gemacht wurden, sowie die FloatToStrF scheitern an den oberen Grenzen von Int64 . Sie verlieren ein paar Bytes, aber ich halte diese Bytes für ziemlich wichtig, da der Zweck des zweiten Wertes in diesem Anzeigeformat darin besteht, eine genaue Zahl zu liefern.

Sobald du alle Teile hast, klebst du sie zusammen. Ich verwende ein hypothetisches IntToStrCommas Funktion hier, und wenn Sie diese als FloatToStrF , fahren Sie fort.

function BytesToDisplay(const num: Int64): string;
var
  // If GB is the largest unit available, then 20 characters is
  // enough for "17,179,869,183.99 GB", which is MaxUInt64.
  buf: array[0..20] of Char;
begin
  if StrFormatByteSize64(num, buf, Length(buf)) = nil then
    raise EConvertError.CreateFmt('Error converting %d', [num]);
  Result := Format('%s (%s bytes)', [buf, IntToStrCommas(num)]);
end;

5voto

Das ist nicht genau das, was Sie suchen, aber ich habe eine Funktion in meiner Bibliothek, die Ihnen vielleicht eine Idee gibt, wie Sie dieses Problem lösen können:

function FormatByteSize(const bytes: Longword): string;
var
  B: byte;
  KB: word;
  MB: Longword;
  GB: Longword;
  TB: UInt64;
begin

  B  := 1; //byte
  KB := 1024 * B; //kilobyte
  MB := 1000 * KB; //megabyte
  GB := 1000 * MB; //gigabyte
  TB := 1000 * GB; //teraabyte

  if bytes > TB then
    result := FormatFloat('#.## TB', bytes / TB)
  else
    if bytes > GB then
      result := FormatFloat('#.## GB', bytes / GB)
    else
      if bytes > MB then
        result := FormatFloat('#.## MB', bytes / MB)
      else
        if bytes > KB then
          result := FormatFloat('#.## KB', bytes / KB)
        else
          result := FormatFloat('#.## bytes', bytes) ;
end;

0voto

dummzeuch Punkte 10604

Dies ist von meiner dzlib-Einheit u_dzConvertUtils :

/// these contants refer to the "Xx binary byte" units as defined by the
/// International Electronical Commission (IEC) and endorsed by the
/// IEE and CiPM </summary>
const
  OneKibiByte = Int64(1024);
  OneMebiByte = Int64(1024) * OneKibiByte;
  OneGibiByte = Int64(1024) * OneMebiByte;
  OneTebiByte = Int64(1024) * OneGibiByte;
  OnePebiByte = Int64(1024) * OneTebiByte;
  OneExbiByte = Int64(1024) * OnePebiByte;

/// <summary>
/// Converts a file size to a human readable string, e.g. 536870912000 = 5.00 GiB (gibibyte) </summary>
function FileSizeToHumanReadableString(_FileSize: Int64): string;
begin
  if _FileSize > 5 * OneExbiByte then
    Result := Format(_('%.2f EiB'), [_FileSize / OneExbiByte])
  else if _FileSize > 5 * OnePebiByte then
    Result := Format(_('%.2f PiB'), [_FileSize / OnePebiByte])
  else if _FileSize > 5 * OneTebiByte then
    Result := Format(_('%.2f TiB'), [_FileSize / OneTebiByte])
  else if _FileSize > 5 * OneGibiByte then
    Result := Format(_('%.2f GiB'), [_FileSize / OneGibiByte])
  else if _FileSize > 5 * OneMebiByte then
    Result := Format(_('%.2f MiB'), [_FileSize / OneMebiByte])
  else if _FileSize > 5 * OneKibiByte then
    Result := Format(_('%.2f KiB'), [_FileSize / OneKibiByte])
  else
    Result := Format(_('%d Bytes'), [_FileSize]);
end;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X