Frage

Dies ist ein einfaches (glaube ich).

Gibt es ein System in Funktion eingebaut, oder eine Funktion, dass jemand erstellt, die von Delphi aufgerufen werden kann, die eine Anzahl von Bytes (zB eine Dateigröße) angezeigt werden, die Art und Weise Windows zeigt in einem Feld Eigenschaften der Datei?

z. Dies ist, wie Windows-Eigenschaftenfeld zeigt verschiedene Größen:

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

Das Display ist intelligent über die Verwendung von Bytes, KB, MB oder GB, und zeigt nur drei signifikante Stellen für das KB, MB und GB. Daraus folgt, dass durch die genaue Anzahl von Bytes in Klammern der Anzeige mit Kommas, um die Tausende zu trennen. Es ist ein sehr schönes Display, gut durchdacht.

Kennt jemand eine solche Funktion?


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

.

Vielen Dank für Ihre hilfreichen Ideen. Ich habe mit dieser kommen, das scheint zu funktionieren:

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;

Dies ist wahrscheinlich gut genug, aber ist es etwas Schöneres?

War es hilfreich?

Lösung

Auch die folgenden Funktionen, die alle im shlwapi Bibliothek .

Jeder von ihnen wird Ihnen den ersten Teil Ihrer gewünschten Anzeigeformat. Überprüfen Sie die Dokumentation oder schreiben Sie Ihre eigenen Tests zu bestätigen, dass sie die Konvertierungen geben Sie erwarten darüber, ob ein Megabyte von 1000 oder 1024 Kilobyte besteht. Für den zweiten Teil des Anzeigeformats, können Sie mit den Antworten auf einen anderen Stack-Überlauf Frage beginnen:

Aber vielleicht diese Frage ist der falsche Weg gibt, da alle Vorschläge zu gehen, sowie FloatToStrF, scheitert an den oberen Grenzen der Int64. Sie werden ein paar Bytes verlieren, aber ich halte diese ziemlich wichtig Bytes da der Zweck des zweiten Wertes in diesem Anzeigeformat ist eine genaue Zahl zu liefern.

Wenn Sie alle Stücke haben, kleben sie zusammen. Ich verwende eine hypothetische IntToStrCommas Funktion hier, und wenn Sie möchten, implementieren, dass als FloatToStrF, nur zu.

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;

Andere Tipps

Nicht genau das, was du bist nach, aber ich habe eine Funktion in meiner Bibliothek, die Ihnen eine Idee geben kann, wie dies in Angriff zu nehmen ein:

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;

Dies ist aus 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;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top