バイト数のフォーマット処理とか

メモ。ファイルやらのバイト数のフォーマット処理とか。まあファイル破断なんかではよく使うわけです。Int64は必須。
変数名が難しいなあ。

FmtUtils.pas

unit FmtUtils;

interface

uses
  SysUtils;

const
  UNIT_BYTES = 1024;
  MAX_UNITS = 6;
  UNITS_STRING: array[0..MAX_UNITS] of string = ('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB');
  DEFAULT_BYTES_FORMAT = '%f %s';

function Int64Power(Base: UInt64; Exponent: Integer): UInt64;
function DetectUnit(Value: UInt64): Integer;
function DetectUnitStr(Value: UInt64): string;
function DetectUnitValue(Value: UInt64): Extended;
function FormatByte(Value: UInt64; Fmt: string = '%f %s'): string;
function CalcBytes(Value: UInt64; UnitValue: Integer): UInt64;

implementation

function Int64Power(Base: UInt64; Exponent: Integer): UInt64;
var
  i: Integer;
begin
  Result := 1;
  for i := 0 to Exponent - 1 do
    Result := Result * Base;
end;

function DetectUnit(Value: UInt64): Integer;
begin
  for Result := 0 to MAX_UNITS do
  begin
    if Value < UNIT_BYTES then Break;
    Value := Value div UNIT_BYTES;
  end;
end;

function DetectUnitStr(Value: UInt64): string;
begin
  Result := UNITS_STRING[DetectUnit(Value)];
end;

function DetectUnitValue(Value: UInt64): Extended;
begin
  Result := Value / Int64Power(UNIT_BYTES, DetectUnit(Value));
end;

function FormatByte(Value: UInt64; Fmt: string = DEFAULT_BYTES_FORMAT): string;
begin
  Result := Format(Fmt, [DetectUnitValue(Value), DetectUnitStr(Value)]);
end;

function CalcBytes(Value: UInt64; UnitValue: Integer): UInt64;
begin
  Result := Value * Int64Power(UNIT_BYTES, UnitValue);
end;

end.

Project1.dpr

使用例

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  FmtUtils in '..\..\lib\FmtUtils.pas';

var
  v: UInt64;
begin
  try
    v := 123456789;
    Writeln(v, ': ', DetectUnitStr(v));
    Writeln(DetectUnitValue(v));
    Writeln(FormatByte(v));
    Writeln(CalcBytes(10, 2), UNITS_STRING[0]);
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

実行結果

>Project1.exe
123456789: MB
 1.17737568855285E+0002
117.74 MB
10485760B

昨日のエントリの容量表示で使ってみると、

Project1.dpr

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  SysStats in '..\..\lib\SysStats.pas',
  FmtUtils in '..\..\lib\FmtUtils.pas';

begin
  try
    Writeln('mem avail(Phy):', FormatByte(GetAvailableMemory));
    Writeln('mem avail(Virtual):', FormatByte(GetAvailableMemory(False)));
    Writeln('mem total(Phy):', FormatByte(GetTotalMemory));
    Writeln('mem total(Virtual):', FormatByte(GetTotalMemory(False)));
    Writeln('disk C:\ avail:', FormatByte(GetAvailableDiskSpace('C:\')));
    Writeln('disk C:\ total:', FormatByte(GetTotalDiskSpace('C:\')));
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

実行結果

>Project1.exe
mem avail(Phy):2.20 GB
mem avail(Virtual):1.98 GB
mem total(Phy):3.25 GB
mem total(Virtual):2.00 GB
disk C:\ avail:138.28 GB
disk C:\ total:195.55 GB