ディスクサイズフォーマット

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

ディスクサイズフォーマット

このレッスンで分かること

  • ファイル一覧を作るたびに 12345678 byte のような生の値で表示していたら、ユーザーは数えるのに疲れます
  • ファイル容量はユーザーが意思決定する材料になります
  • 1024 倍 ごとに単位が上がっていきます

ディスクサイズフォーマット とは

バイトを単位付き文字列で読みやすく整形する関数を作る。本レッスンでは、ディスクサイズフォーマット の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

ファイル一覧を作るたびに 12345678 byte のような生の値で表示していたら、ユーザーは数えるのに疲れます。12.3 MB のように 単位付き文字列 を返すユーティリティは、ターミナルツールから Web の管理画面まで広く使われる基本部品です。Linuxls -lh du -hNode.jspretty-bytesJavaApache Commons IO など、どの言語のエコシステムにも標準の流儀があります。

サイズ整形は エンジニアが最初に書く関数 の代表格。配列 条件分岐 丸め の総合演習でもあります。

なぜ整形が大事か

ファイル容量はユーザーが意思決定する材料になります。バックアップ のサイズ、ダウンロード の所要時間、課金 の対象容量、すべてが 表示の読みやすさ で UX が変わります。生のバイト数単位付き文字列 を両方ログに残しておくと、デバッグユーザー表示 を両立できます。

単位の階段

1024 倍 ごとに単位が上がっていきます。B KB MB GB TB の 5 段階を覚えておけば、現代のストレージサイズのほぼすべてをカバーできます。PB (ペタバイト) や EB (エクサバイト) は大規模システム向けで、本問題では使いません。

Python

UNITS = ["B", "KB", "MB", "GB", "TB"]

単位は 配列 で持つのが鉄板です。while ループで 1024 以上のあいだ index を進め、単位 を切り替えていきます。switchif/else if の長い分岐でも同じ結果は出せますが、配列 + ループ の方が 階段が増えたときに保守しやすい 構造です。

アルゴリズムの全体像

手順は次の通りに進めます。

  • 初期値 size = bytes index = 0
  • size >= 1024 かつ index < 4 であれば size /= 1024 index += 1
  • ループ終了後、size を小数第 1 位で丸めて 単位 と連結
diagram (will load when visible)

文字列フォーマットの作法

f-string (Python) や テンプレートリテラル (JS) を使うと記述が短くなります。小数第 1 位 まで残すには f"{size:.1f} {unit}" のように フォーマット指定子 を使います。JS では size.toFixed(1) です。

JavaScript

function formatSize(bytes) { const units = ["B", "KB", "MB", "GB", "TB"]; let size = bytes; let i = 0; while (size >= 1024 && i < units.length - 1) { size /= 1024; i += 1; } return `${size.toFixed(1)} ${units[i]}`; }

戻り値が 文字列 なので テストケース が比較しやすい一方、小数点表示 のロケール差に注意します。

0 と小さい値

0 byte0.0 B を返します。100 byte100.0 B です。最初から 1024 未満なら while に入らず、index0 のまま B 表示になります。これが 初期値 0 の良いところで、空ファイル も自然に表示できます。

整数の丸めと表示の丸め

JS の toFixed(1) は仕様上は最近接への丸めを意図していますが、対象値が IEEE 754 浮動小数点で正確に表せない場合に結果がブレます。Python の :.1f は CPython の実装が round-half-to-even(偶数丸め)を採用していますが、こちらも IEEE 754 の表現誤差が先に効くため、期待どおりに偶数丸めが働かないケースがあります。どちらも 0.05 のように二進数で正確に表せない値では、丸め結果が意図と異なる場合があります。会計や監査領域では Decimal 系の専用型に切り替えるのが鉄則です。

Python と JS の細かい違い

Python の f"{size:.1f}"1.0"1.0" と返します。JavaScript の size.toFixed(1) も同様に "1.0" を返します。一方、JavaString.format("%.1f", size) はロケールで ,. が切り替わる罠があります。デフォルト Locale.US を明示するか、String.format(Locale.US, ...) を使うのが安全です。

よくある間違い

  • index の上限チェックを忘れて TB を超え units[5]undefined になる
  • Math.floor を使ってしまい、1.9 MB1.0 MB になる
  • KBkB の表記揺れ
  • ロケールにより 小数点, になり 1,5 KB のように表示される

整形関数は 挙動が文字列で見える ぶん、テストが書きやすく、仕様変更 にも強くなります。

やってみよう

  • 1024 ベース ではなく 1000 ベース (SI 単位) の版を書く
  • i18n 対応で KBキロバイト に切り替えられるようにする
  • 入力が 負の値 のときに "-1.0 KB" のように 符号付き を返す版を書く
  • 小数第 2 位まで残す precision 引数を追加した版を書く

よくある質問

Q. このトピックを覚える意味は何ですか?

A. アプリ層の上っ面だけ追わず、内部で何が起きているかを理解するための土台になります。例えばエンコーディングや進数変換は、文字化け・整数オーバーフロー・データサイズ計算で必ず出会う知識です。実務での問題解決スピードが格段に上がります。

Q. 実務でこの知識を使う場面は?

A. API の Content-Length 計算、ファイルアップロードのサイズ制限、画像処理での色深度計算など、低レベルな数値を扱う場面で頻出します。OS・ネットワーク・暗号の理解にも繋がるため、CS の共通言語と思って習得しておくと一生使える知識です。

Q. 他の章とどう繋がりますか?

A. 後続の章で扱うデータ構造(スタック・キュー)、アルゴリズム(探索・ソート)の基礎になります。「データを 32 bit でどう表現するか」「メモリにどう載せるか」が分かると、後続トピックの実装が腹落ちしやすくなります。

次のレッスン

次は キャッシュヒット率 に進みましょう。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. サイズ整形 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. サイズ整形 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. formatSize という名前の関数を実装すること
  2. B / KB / MB / GB / TB の 5 単位を扱うこと
  3. 小数第 1 位までの文字列を返すこと

入出力例

test-cases.txt

formatSize(0)"0.0 B" formatSize(500)"500.0 B" formatSize(1024)"1.0 KB" formatSize(1500)"1.5 KB" formatSize(1048576)"1.0 MB" formatSize(1073741824)"1.0 GB"

ヒント

main.py
main.py
学習モード

メモ

ディスクサイズフォーマット

⌘S で保存