gzip解凍の内部構造と ZIP の違い
「gzipの中身がどう動いているか」と「ZIPと何が違うのか」という本質的な理解です。 ここでは、Java の話に限らず、圧縮形式そのものの仕組みを分かりやすく噛み砕いて説明します。 そして、必要なところには gzip や ZIP の追加解説に飛べるように Guided Link を入れています。
gzip解凍の内部構造
gzip は「圧縮形式」ではなく “圧縮されたデータを包むファイルフォーマット” です。 中身の圧縮アルゴリズムは DEFLATE という方式が使われています。
DEFLATE の内部構造
DEFLATE は次の二段構えで圧縮します。
1. LZ77(辞書圧縮)
繰り返し出てくるデータを「過去のどこにあったか」を参照する形で短く表現します。
例:
AAAAABBBBBBCCCC
というデータがあったら、
- 「A が 5 回続く」
- 「B が 6 回続く」
- 「C が 4 回続く」
というように「繰り返し」を参照で表現します。
2. ハフマン符号化(可変長ビット圧縮)
よく出るデータは短いビット列、 あまり出ないデータは長いビット列で表現することで、全体をさらに圧縮します。
gzip解凍の流れ
gzipファイルを解凍するときは、次の順番で処理されます。
1. gzipヘッダを読む
gzipファイルの先頭には「これは gzip だよ」というメタ情報が入っています。
例:
- 圧縮日時
- OS種別
- オプションフラグ
- オリジナルファイル名(入っている場合)
2. DEFLATE のビット列を読み取る
gzip の本体部分は「DEFLATE の圧縮データ」です。 ここを読みながら、ハフマン符号を解読し、LZ77 の参照を展開していきます。
3. 展開されたバイト列を出力する
最終的に「元の生データ(byte[])」が復元されます。
Java の GZIPInputStream は、この一連の処理を内部で自動的に行っています。
ZIP の内部構造
ZIP は gzip と違い、「複数ファイルをまとめるアーカイブ形式」です。 圧縮方式としては同じ DEFLATE を使うことが多いですが、構造がまったく違います。
ZIP の特徴
1. 複数ファイルを格納できる
ZIP は「フォルダのような構造」を持ちます。
report.csv
image.png
config.json
などをひとまとめにできます。
2. 各ファイルごとに圧縮方式を選べる
ZIP 内の各ファイルは、次のように個別に圧縮方式を持ちます。
- DEFLATE(一般的)
- STORE(圧縮しない)
- BZIP2(拡張)
- LZMA(拡張)
gzip は「1ファイルだけ」なので、この柔軟性はありません。
3. ZIP には「中央ディレクトリ」がある
ZIP の末尾には「中央ディレクトリ」というメタ情報があり、 ZIP 内のファイル一覧・サイズ・圧縮方式などがまとめて記録されています。
これにより ZIP は「高速にファイル一覧を取得できる」という利点があります。
gzip と ZIP の違い(本質的な比較)
| 項目 | gzip | ZIP |
|---|---|---|
| 格納できるファイル数 | 1つだけ | 複数ファイル |
| 圧縮方式 | DEFLATEのみ | DEFLATEが多いが複数方式を選べる |
| メタ情報 | 最小限(日時・OSなど) | ファイル一覧・サイズ・圧縮方式など大量 |
| 用途 | 単一ファイルの圧縮 | アーカイブ(まとめて保存) |
| Javaでの扱い | GZIPInputStream / GZIPOutputStream | ZipInputStream / ZipOutputStream |
gzip と ZIP の使い分け(実務での判断)
gzip を使うべき場面
- ログファイルを圧縮して保存したい
- CSV を圧縮して転送したい
- Web API のレスポンスを軽量化したい
- 単一ファイルを高速に圧縮したい
ZIP を使うべき場面
- 複数ファイルをまとめて保存したい
- フォルダ構造ごとバックアップしたい
- ユーザーに「まとめてダウンロード」させたい
- ファイルごとに圧縮方式を変えたい
まとめ:gzipとZIPの違いを一言で言うと
gzipは「1つのファイルを圧縮する袋」 ZIPは「複数ファイルをまとめる箱」
中身の圧縮方式は似ていても、目的と構造がまったく違います。
