bzip2(1)

名称
bzip2, bunzip2 - ブロックソーティングによるファイル圧縮器, v1.0.2
bzcat - ファイルを伸長して標準出力へ書き出す
bzip2recover - 破損した bzip2 ファイルからデータを復元

書式
bzip2 [ -cdfkqstvzVL123456789 ] [ filenames ... ]
bunzip2 [ -fkvsVL ] [ filenames ... ]
bzcat [ -s ] [ filenames ... ]
bzip2recover filename

解説
bzip2 は Burrows-Wheeler ブロックソーティングテキスト圧縮アルゴリズムと Huffman 符号を使ってファイルを圧縮します。圧縮率は大抵、より一般的な LZ77/LZ78 をベースとした圧縮器より大変良く、性能は 統計的圧縮器の PPM ファミリに迫っています。 コマンドラインオプションは意図的に GNU gzip のものに似せてありますが、同一ではありません。 bzip2 はコマンドラインフラグを伴ったファイル名のリストを受け取ります。 各ファイルは "original_name.bz2" という名前の 圧縮済みファイルで置き換えられます。 圧縮された各ファイルは、元のファイルと同じ更新時刻およびパーミッションを 持ち、そして可能なら同じ所有者となります。 これによりこれらの属性は伸長時に正しく復元可能となります。 ファイル名の扱いは単純で、 元ファイルの名前、パーミッション、所有者、日付の概念が無いファイルシステムや、 MS-DOS のようにファイル名の長さに大きな制限があるファイルシステム では、それらを保存する機構はありません。 bzip2 と bunzip2 は、デフォルトでは既存のファイルを上書きしません。 上書きしたい場合は -f フラグを指定してください。 ファイル名が指定されない場合、 bzip2 は標準入力を圧縮して標準出力へ書き出します。この場合 bzip2 は圧縮された結果を端末へ書き出しません。それは全く読むことができず、 出力することは無意味だからです。 bunzip2 (または bzip2 -d) は指定されたすべてのファイルを伸長します。 bzip2 で生成されたのではないファイルを検知・無視し、 さらに警告を発します。 bzip2 は以下のようにして圧縮済みファイルの名前から 伸長後のファイル名を推測します:
       filename.bz2 は filename とします
       filename.bz は filename とします
       filename.tbz2 は filename.tar とします
       filename.tbz は filename.tar とします
       anyothername は anyothername.out とします ファイル名が .bz2, .bz, .tbz2 または .tbz のような、認識できる名前で終わっていない場合、 bzip2 は元のファイル名が推測できない旨を通知して .out を付加した名前を元のファイル名として使います。 圧縮の場合と同様に、ファイル名が指定されない場合は 標準入力を伸長して標準出力へ書き出します。 bunzip2 は 2 つ以上の圧縮済みファイルを連結したファイルを正しく伸長します。 得られるファイルは、伸長後のファイルを連結したものです。 連結した圧縮ファイルに対しても健全性のテスト (-t) がサポートされています。 -c フラグを与えることで、ファイルを圧縮または伸長した結果を 標準出力へ書き出すことができます。このフラグを与えて、 複数のファイルを圧縮または伸長することができます。結果は 標準出力へ順番に書き出されます。この方式による複数ファイルの圧縮では、 複数の圧縮ファイルからなるストリームが生成されます。 このストリームは、バージョン 0.9.0 以降の bzip2 でしか正しく伸長できません。これより前のバージョンの bzip2 では、ストリーム中の最初のファイルを伸長した後に停止します。 bzcat (または bzip2 -dc) は指定された全てのファイルを伸長し、標準出力に書き出します。 bzip2 は引数として環境変数 BZIP2 と BZIP を順番に読み、 コマンドラインから読んだ引数より先に処理します。 これはデフォルトの引数を与えるのに便利です。 圧縮後のファイルが元のファイルよりも少し大きくなる場合でも、 常に圧縮は行われます。 圧縮機構には常に 50 バイトのオーバヘッドがあるので、 約 100 バイトよりも小さなファイルは大きくなる傾向があります。 ランダムなデータ (ほとんどのファイル圧縮器の出力も) は 1 バイト当たり約 8.05 ビットで符号化され、約 0.5% 大きくなります。 保護のための自己チェックとして、 bzip2 は、伸長後のファイルと元のファイルとの同一性を確かめる ために 32 ビット CRC を使います。 これにより、圧縮済みデータの破損や bzip2 のまだ見つかっていないバグ (ほとんど無いはすです) から守ります。 データの破壊が検出できない確率は極めて小さく、各ファイルの処理 40 億回あたり 1 回程度です。 ただし、このチェックは伸長の時にしか行われず、したがって 何か間違いが発生したことしか分かりません。 圧縮前の元データを復元するのには役に立ちません。 破損したファイルからデータを復元するのに bzip2recover を試みることはできます。 戻り値: 正常終了の場合は 0 が返されます。 実行環境の問題 (ファイルが見つからない、無効なフラグ、入出力エラーなど) の場合は 1 が戻ります。圧縮ファイルが破損している場合は 2 が戻ります。 bzip2 にパニックを引き起こす内部整合性エラー (例えばバグ) の場合は 3 が戻ります。

オプション

-c --stdout
    圧縮または伸長した結果を標準出力に書き出します。

-d --decompress
    伸長を強制します。 bzip2, bunzip2, bzcat は実際には同じプログラムで、どの動作をするのかは、 どの名前が使われたかに基づいて決められます。 このフラグはそれよりも優先され、 bzip2 に伸長を強制させます。

-z --compress
    -d の反対: 起動時の名前にかかわらず、圧縮を強制します。

-t --test
    指定されたファイルの健全性チェックをしますが、伸長はしません。 実際には伸長を試み、その結果は捨てています。

-f --force
    出力ファイルの上書きを強制します。通常 bzip2 は既存の出力ファイルを上書きしません。さらに bzip2 にファイルへのハードリンクを切断させます。この オプションが指定されていない場合は、ハードリンクの切断はされません。 bzip2 は通常、正しいマジックヘッダバイトを持たないファイルの伸長を拒否します。 強制 (-f) すると、そのようなファイルを修正せずにそのまま通過させます。 これは GNU gzip の動作と同じです。

-k --keep
    圧縮または伸長後でも入力ファイルを保存します (削除しません)。

-s --small
    圧縮、伸長、テストの際のメモリ使用量を減らします。 ブロックバイトあたり 2.5 バイトしか必要としないように変更された アルゴリズムを使って、ファイルの伸長やテストが行われます。 全てのファイルが 2300k のメモリで伸長できますが、 通常の約半分の速度になってしまいます。 圧縮時に -s を使うと 200k のブロックサイズが選択されます。 メモリ使用量はほぼ同じ大きさに制限されますが、圧縮率が犠牲になります。 つまり、マシンに搭載されているメモリが少なければ (8 メガバイト以下) つねに -s フラグを使ってください。後述するメモリ管理の項目を参照してください。

-q --quiet
    本質的でない警告メッセージは出力しません。入出力エラーと 致命的なイベントに関連するメッセージは出力されます。

-v --verbose
    詳細表示モードです。処理されたファイル毎に圧縮率を表示します。 さらに -v を与えると詳細表示のレベルが上がり、主に診断を目的とする 多くの情報が出力されます。

-L --license -V --version
    ソフトウェアのバージョン、ライセンス条項とその条件が表示されます。

-1 (または --fast) から -9 (または --best)
    圧縮時のブロックサイズを 100 k, 200 k .. 900 k に設定します。 伸長時には何も影響がありません。下のメモリ管理の項目を参照してください。 --fast と --best という別名は、 第一義的には GNU gzip との互換性のためです。 特に、--fast は非常に高速になるわけではありません。 また、--best は単にデフォルト動作を選択するだけです。

--  これ以降の引数についてはダッシュで始まるものでもファイル名として 扱われます。これによりダッシュで始まるファイル名も扱うことが できます。例えば次のように使います: bzip2 -- -myfilename

--repetitive-fast --repetitive-best
    これらのフラグは、バージョン 0.9.5 以降では冗長です。 これらは以前のバージョンで整列アルゴリズムの動作を大雑把に 制御するために提供されたもので、時々は役立っていたものでした。 0.9.5 以降でこれらのフラグが無関係になる改良されたアルゴズムが使われています。

メモリ管理
bzip2 は大きなファイルをブロック毎に圧縮します。ブロックサイズは 達成される圧縮率と、圧縮または伸長に要するメモリの量に影響します。 -1 から -9 までのフラグは、それぞれブロックサイズを 100,000 バイトから 900,000 バイト (デフォルト) に指定します。伸長時には、 圧縮時に使われたブロックサイズが圧縮ファイルのヘッダから読まれ、 bunzip2 はファイルを伸長するのに十分なだけのメモリを確保します。 ブロックサイズは圧縮ファイルに格納されているので、 伸長時にはフラグ -1 から -9 は無関係であり、無視されます。 圧縮と伸長に必要なメモリ量は次のように見積もることができます:
       圧縮: 400k + ( 8 x ブロックサイズ )
       伸長: 100k + ( 4 x ブロックサイズ ), または
               100k + ( 2.5 x ブロックサイズ ) ブロックサイズを大きくするにしたがい、効果は急速に減少していきます。 大部分の圧縮は最初の 200k あるいは 300k のブロックサイズで得られます。 この事実を覚えておけば、小規模なマシンで bzip2 を使うときに役立つでしょう。 また、圧縮時に選択されたブロックサイズにより 伸長に必要なメモリ量が設定されることを知っておくのも重要です。 ブロックサイズがデフォルトの 900k で圧縮されたファイルを bunzip2 が伸長する時は 3700 キロバイト必要です。 4 メガバイトしかメモリを搭載していないマシンであらゆるファイルを 伸長するために、 bunzip2 には、約半分の 2300 キロバイトの量のメモリを使うオプションがあります。 伸長速度も半分になるので、このオプションは必要な場合にのみ使うべきです。 そのフラグは -s です。 一般にはメモリ量が許す限り大きなブロックサイズを試して使ってください。 こうすることで最も高い圧縮率を達成できます。 ブロックサイズは、圧縮と伸長の速度にほとんど影響しません。 単一のブロックに収まっているファイルに関しては、もう一つの 重要なポイントがあります。これは大きなブロックサイズにした場合に ほとんどのファイルがあてはまります。 この場合、ファイルはブロックより小さいので、 利用される実メモリの量はファイルの大きさに比例します。 例えば、長さが 20,000 バイトのファイルを -9 というフラグを 与えて圧縮する場合、圧縮器は約 7600k のメモリを割り当てますが、 そのうち 400k + 20000 * 8 = 560 キロバイトしか使いません。 同様に伸長器は 3700k を割り当てますが、 100k + 20000 * 4 = 180 キロバイトしか使いません。 異なるブロックサイズにおける最大メモリ使用量をまとめた表を示します。 また全部で 14 ファイル、合計 3,141,622 バイトからなる カルガリーテキスト圧縮文献集を圧縮した後のサイズも示します。 このカラムから、ブロックサイズによって圧縮がどのように変わるかを 知ることができます。文献集は比較的小さなファイルが多いので、 この表は大きなファイルに対して大きなブロックサイズを使った場合の利点を 過小評価する傾向にあります。
            圧縮時 伸長時 伸長時 文献集の
   フラグ 使用量 使用量 使用量 (-s) サイズ
     -1 1200k 500k 350k 914704
     -2 2000k 900k 600k 877703
     -3 2800k 1300k 850k 860338
     -4 3600k 1700k 1100k 846899
     -5 4400k 2100k 1350k 845160
     -6 5200k 2500k 1600k 838626
     -7 6100k 2900k 1850k 834096
     -8 6800k 3300k 2100k 828642
     -9 7600k 3700k 2350k 828642

破損したファイルからデータを復元する
bzip2 はファイルを大抵 900 キロバイトのブロック毎に圧縮します。 それぞれのブロックは独立に扱われます。 メディアや転送時の誤りにより、 複数ブロックからなる .bz2 ファイルが破壊された場合でも、 ファイル中の破損していないブロックからデータを復元できる 可能性があります。 各ブロックの圧縮された表現は 48 ビットのパターンで区切られており、 これを使ってブロックの境界を十分確実に見つけることができます。 各ブロックは 32 ビットの CRC を持ち、破損したブロックを 破損していないブロックと区別することができます。 bzip2recover は .bz2 ファイル中のブロックを探し、 それぞれのブロックを別々の .bz2 ファイルへ書き出す 単純なプログラムです。その後で bzip2 -t を使って得られた各ファイルの健全性をテストし、破損していない ファイルを伸長することができます。 bzip2recover は単一の引数として破損したファイルの名前をとり、 抽出されたブロックを含む "rec00001file.bz2", "rec00002file.bz2" … という大量のファイルを書き出します。出力されるファイル名は その後の処理でワイルドカードが使えるように設計されています。 例えば "bzip2 -dc rec*file.bz2 > recovered_data" とすれば、 ファイルを正しい順番で処理できます。 bzip2recover は大きな .bz2 ファイルを扱うときに最も役に立ちます。 大きな .bz2 ファイルには大量のブロックが含まれているからです。 破損したブロックの復旧はできないため、 単一のブロックだけで構成されている破損ファイルに対しては 役に立たないのは明らかです。 メディアや転送時の誤りで発生するデータの損失の可能性を 最小にしたい場合には、小さなブロックサイズで圧縮することが 考えられます。

性能に関する注釈
圧縮におけるソート段階では、ファイル中の類似した文字列を集めます。 このため、"aabaabaabaab ..." のように記号が何回も長く (数百回) 繰り返されているファイルを圧縮する場合は通常より遅くなります。 バージョン 0.9.5 以降では、以前のバージョンに比べてこの点が かなり改善されています。 圧縮時間の最も悪い場合と平均的な場合の比は 10:1 の範囲です。 以前のバージョンでは 100:1 というような比でした。 オプション -vvvv を与えることで、進行状況を大変詳しく見ることができます。 伸長の速度はこれらの現象に影響されません。 bzip2 は動作のために大抵数メガバイトのメモリを確保し、全くランダムに その領域を変更します。 これは、マシンがキャッシュミスに対してどれだけの速度で対処できるかが、 圧縮や伸長の性能を大きく決定するということを意味します。 このため、キャッシュミスの割合を減らすようにコードを少し変更 することにより、性能が大きく向上することがわかっています。 bzip2 はとても大きなキャッシュを持つマシンで最高の性能を出すと考えられます。

警告
入出力エラーのメッセージはそれほど役立ちません。 bzip2 はできるだけ入出力エラーを検知し、正しく終了するように試みますが、 何が問題なのかの詳細は、時々かなり間違ったものになることがあります。 このマニュアルページは bzip2 のバージョン 1.0.2 について述べています。 このバージョンが生成する圧縮データは、前方互換性と、以前の公開リリースである バージョン 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1 に対する後方互換性があります。 ただし、次の例外があります: 0.9.0 以降は複数の圧縮ファイルを連結した ファイルを伸長できますが、0.1pl2 はできません。 ストリームの先頭にあるファイルを伸長した後に停止します。 バージョン 1.0.2 以前の bzip2recover では、圧縮ファイル中のビットの位置を表現するために 32 ビット整数を 使っているので、512 メガバイトより長い圧縮ファイルを扱うことが できませんでした。 バージョン 1.0.2 以上では、 64 ビット整数をサポートするプラットフォーム (GNU がサポートするものと Windows) の一部で、 64 ビット整数を使用しています。 bzip2recover にこの制限が有るか無いかを確認するには、 引数無しで実行してください。 MaybeUInt64 を符号無し 64 ビット整数にして再コンパイルすれば、 制限無しバージョンを作成可能です。

作者
Julian Seward, jseward@acm.org http://sources.redhat.com/bzip2 bzip2 に含まれるアイディアは (少なくとも) 以下の人々によるものです: Michael Burrows と David Wheeler (ブロックソート変換)、 David Wheeler (再掲、Huffman 符号化器)、 Peter Fenwick (オリジナルの bzip における構造化コーディングモデルと多くの改良)、 Alistair Moffat, Radford Neal そして Ian Witten (オリジナルの bzip における算術符号化器)。私は、彼らの助けや支援そしてアドバイスに 感謝しています。 ドキュメントの情報源については、ソース配布中のマニュアルを 参照してください。 Christian von Roques は、圧縮速度の向上のために より速いソートアルゴリズムを探すことを勧めてくれました。 Bela Lubkin は、圧縮速度が最も遅い場合の改良を勧めてくれました。 bz* スクリプトは、GNU gzip 由来です。 多くの人がパッチを送り、移植性の問題について助けの手を差しのべ、 マシンを貸し、アドバイスをくれました。これらは概ね助けになるものでした。