这是一个简单的(我认为)。
是否有一个内置系统的系统,或某人创建的可以从Delphi调用的函数,它将显示多个字节(例如文件大小),Windows在文件的属性框中显示的方式?
e.g。这是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位有效数字。然后通过用逗号分隔数千个括号显示括号中的确切字节数。这是一个非常好的展示,深思熟虑。
有谁知道这样的功能?
编辑:我很惊讶没有这个功能。
感谢您的有益想法。我想出了这个,这似乎有用:
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;
这可能已经足够好了,但有什么更好的吗?
答案 0 :(得分:12)
请参阅shlwapi library中的以下所有功能。
StrFormatByteSizeA
(DWord参数)StrFormatByteSizeW
(Int64参数)StrFormatByteSize64
(在Unicode模式下,它确实是StrFormatByteSizeW
)StrFormatByteSizeEx
(Vista SP2;可以控制舍入)它们中的任何一个都会为您提供所需显示格式的第一部分。检查文档或编写您自己的测试,以确认它们是否提供了您预期的兆字节是否包含1000或1024千字节的转换。对于显示格式的第二部分,您可以从另一个Stack Overflow问题的答案开始:
但也许这个问题是错误的途径,因为那里的所有建议以及FloatToStrF
都在Int64
的上限失败了。你会丢失几个字节,但我认为那些非常重要的字节,因为该显示格式中第二个值的目的是提供一个确切的数字。
一旦你掌握了所有碎片,就将它们粘在一起。我在这里使用了一个假设的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 :(得分:5)
不完全是你所追求的,但我的库中有一个功能,可以让你知道如何处理这个:
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;
答案 2 :(得分:0)
这是来自我的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;