2008年3月17日月曜日

tar ファイルのファイル末尾データについて

弊社の IP*Works! Zip 製品では tar 形式のアーカイブを扱うことができます。その関係で幾つかのテストデータを SuSE や KNOPPIX 等で作ってテストしていて気づいたのですが、Gnu tar で作成した tar ファイルはアーカイブの末尾に使用されないデータを含んでおり、ファイルサイズ (バイト数) が常に 10240 の整数倍になっていました。

一方弊社製品で作成する場合は, 512 の整数倍のサイズですが、必ずしも 10240 バイトの整数倍にはなりません。両者は特に問題なく生成も展開も互換性が保たれています。

少々気になったのでいろいろ調べていたところ、以下のようなことだと判明しました。

・tar は Tape ARchiver の略であり、元来はテープデバイスへの書き込みを目的としていた。
・テープデバイスは低速であり、Unix の書き込み単位 (512 バイト) はブロック化して書き込まないと効率が悪い。
・その関係で、Gnu tar の既定値ではブロック化係数 (blocking factor) が 20 になっている。

その結果、既定値を使用して tar ファイルを作成するとそのサイズは 512 x 20 = 10240 バイトの整数倍になります。なおアーカイブメンバーは必ずしもぴったりこのブロックに収まるわけではありませんので、アーカイブの末尾位置を明示するために特別なデータ (EOA: End-of-Archive マーク) をヘッダパートに書き込んで明示します。(そして、EOA 以降のデータは無視されます。)

弊社製品で生成する tar アーカイブも形式としては同様ですが、ブロック化係数が 1 として処理されるため、EOA より後にデータは書き込まれません。このため、生成されるアーカイブのサイズは常に 512 の整数倍となります。

また、EOA 以降のデータに何が入るかは規定されていません。このため、tar の実装によって

・以前のデータ断片が残ったままのもの
・EOA 以降を 0x00 等でクリアするもの

があります。前者の場合、一見意味のあるデータがファイル末尾に存在しているように見えますが、EOA 以降のデータは tar アーカイブとしては意味を持ちませんので、自分で tar アーカイブを処理する場合には注意が必要です。

※もちろん弊社の IP*Works! ZIP 製品に含まれる tar コンポーネントは正しく EOA を認識し、EOA 以降にブロッキング由来の不要データが存在してもそれらは無視されます。

0 件のコメント: