Windows と同じようにバイト数を表示する Delphi 関数
-
18-09-2019 - |
質問
これは簡単なことです(と私は思います)。
バイト数を表示するシステム組み込み関数、または誰かが作成した Delphi から呼び出せる関数はありますか (例:ファイルサイズ)、Windows がファイルのプロパティ ボックスに表示する方法は?
例えばWindows プロパティ ボックスにさまざまなサイズが表示される方法は次のとおりです。
539 bytes (539 bytes)
35.1 KB (35,974 bytes)
317 MB (332,531,365 bytes)
2.07 GB (2,224,617,077 bytes)
表示はバイト、KB、MB、GB を適切に使用しており、KB、MB、GB の有効数字は 3 桁のみ表示されます。その後、正確なバイト数を括弧内に表示し、1000 単位をカンマで区切ります。よく考えられた、とても素敵なディスプレイです。
誰かそのような機能を知っていますか?
編集:この機能がなかったのには非常に驚きました。
役立つアイデアをありがとうございます。私はこれを思いつきました、それはうまくいくようです:
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;
おそらくこれで十分だと思いますが、もっと良いものはありますか?
解決
次の関数を参照してください。 シュルワピ 図書館.
StrFormatByteSizeA
(DWordパラメータ)StrFormatByteSizeW
(Int64パラメータ)StrFormatByteSize64
(Unicode モードでは、実際にはStrFormatByteSizeW
)StrFormatByteSizeEx
(Vista SP2;丸めを制御できます)
いずれも、希望の表示形式の最初の部分を提供します。ドキュメントを確認するか、独自のテストを作成して、メガバイトが 1000 キロバイトで構成されているか、1024 キロバイトで構成されているかに関して期待どおりの変換が行われることを確認します。表示形式の 2 番目の部分では、スタック オーバーフローの別の質問への回答から始めることができます。
- 通貨に換算するにはどうすればいいですか? (彼は本当にお金についてではなく、コンマの挿入方法を尋ねていました。)
しかし、そこにあるすべての提案や、 FloatToStrF
, 、上限で失敗します。 Int64
. 。数バイトが失われますが、その表示形式の 2 番目の値の目的は正確な数値を提供することであるため、これらのバイトは非常に重要であると考えられます。
すべてのパーツが揃ったら、接着して組み立てます。仮説を使用しています IntToStrCommas
ここで関数を使用し、それを次のように実装したい場合 FloatToStrF
, 、 どうぞ。
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;
他のヒント
あなたは後にしているが、私はあなたにこれを取り組むためにどのようにアイデアを与える可能性があり、私のライブラリ内の関数を持っていない、まさに1:
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;
これは私のdzlibユニット 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;