ここにはトレードオフがあることを理解することが重要です。
tar
はテープアーカイバを意味します。テープでは、ほとんどの場合、順次読み取りと書き込みを行います。テープは現在ほとんど使用されていませんがtar
、ストリームとしてデータを読み書きする機能のために使用されています。
できるよ:
tar cf - files | gzip | ssh host 'cd dest && gunzip | tar xf -'
などではできませんzip
。
zip
最初にシーク可能なファイルにローカルに保存せずに、アーカイブのコンテンツをリストすることもできません。次のように考えます:
curl -s https://github.com/dwp-forge/columns/archive/v.2016-02-27.zip | unzip -l /dev/stdin
動作しません。
コンテンツをすばやく読み取るzip
などを行うには、インデックスを作成する必要があります。そのインデックスは、ファイルの最初(ストリームではなく通常のファイルにのみ書き込むことができます)または最後に保存できます。つまり、アーカイバは最後に印刷する前にすべてのアーカイブメンバーを覚えておく必要があります。また、切り捨てられたアーカイブは復元できない可能性があります。
これはまた、アーカイブメンバーを個別に圧縮する必要があることを意味します。これは、特に小さなファイルが多い場合、圧縮率がはるかに低くなることを意味します。
などの形式のもう1つの欠点zip
は、アーカイブが圧縮にリンクされているため、圧縮アルゴリズムを選択できないことです。どのように参照してください。tar
アーカイブはで圧縮するために使用されるcompress
(tar.Z
)、その後でgzip
、その後、bzip2
その後、xz
新しい、よりパフォーマンスの高い圧縮アルゴリズムが考案されたとして。暗号化についても同様です。zip
今日の暗号化を信頼するのは誰ですか?
さて、tar.gz
アーカイブの問題は、解凍するために必要なことではありません。多くの場合、圧縮解除はディスクからの読み取りよりも高速です(メモリにキャッシュされていない場合、大きなtgzアーカイブの内容をリストする方が、圧縮されていない同じものをリストするよりも速いでしょう)が、アーカイブ全体を読み取る必要があります。
インデックスをすばやく読み取れないことは、実際には問題ではありません。アーカイブのテーブルコンテンツを頻繁に読み取る必要があると思われる場合は、そのリストを別のファイルに保存するだけで済みます。たとえば、作成時に次のことができます。
tar cvvf - dir 2> file.tar.xz.list | xz > file.tar.xz
IMOのさらに大きな問題は、アーカイブのシーケンシャルな側面が原因で、アーカイブの最初のセクション全体を読み取らずに個々のファイルを抽出できないことです。IOW、アーカイブ内でランダムな読み取りを行うことはできません。
さて、シーク可能なファイルについては、そのようにする必要はありません。
でtar
アーカイブをgzip
圧縮すると、全体として圧縮されます。圧縮アルゴリズムは、最初に表示されたデータを使用して圧縮するため、最初から圧縮を解除する必要があります。
ただし、xz
データを個別のチャンク(効率的に圧縮するために十分な大きさ)でデータを圧縮するようにフォーマットを構成できます。つまり、これらの圧縮チャンクの最後にインデックスを保持している限り、シーク可能なファイルについては、ランダムに(少なくともチャンクで)非圧縮データ。
pixz
(並列xz
)は、tar
アーカイブを圧縮するときにその機能を使用して、xz
ファイルの最後にアーカイブの各メンバーの開始のインデックスも追加します。
彼らが圧縮されているのであれば、シーク可能なファイルだけでなく、ためにあなたは、(メタデータなしが)すぐにtarアーカイブのコンテンツのリストを取得することができますpixz
:
pixz -l file.tar.xz
ただし、アーカイブ全体を読み取らずに、個々の要素を抽出することもできます。
pixz -x archive/member.txt < file.tar.xz | tar xpf -
さて、なぜUnixのようなもの7z
やzip
めったに使用されないのかについては、ほとんどがUnixファイルをアーカイブできないためです。これらは他のオペレーティングシステム用に設計されています。これらを使用してデータを忠実にバックアップすることはできません。所有者(IDと名前)、権限などのメタデータを保存できません。シンボリックリンク、デバイス、FIFOなどを保存できません。ハードリンクに関する情報や、拡張属性やACLなどの他のメタデータ情報を保存できません。
それらの一部は、任意の名前のメンバーを保存することさえできません(一部は、バックスラッシュ、改行、コロン、または非ASCIIファイル名で窒息します)(一部のtar
形式にも制限があります)。
tgz / tar.xzファイルをディスクに解凍しないでください!
明白でない場合は、tgz
or tar.bz2
、tar.xz
...アーカイブを次のように使用しません。
unxz file.tar.xz
tar tvf file.tar
xz file.tar
.tar
ファイルシステム上に圧縮されていないファイルがある場合は、何か問題が発生しています。
それらのxz
/ bzip2
/ gzip
ストリームコンプレッサーの全体のポイントは、次のようなパイプラインで、オンザフライで使用できることです。
unxz < file.tar.xz | tar tvf -
現代のtar
実装は自分でunxz
/ gunzip
/ を呼び出す方法を知っているbzip2
ので、
tar tvf file.tar.xz
一般的にも機能します(また、データをその場で解凍し、圧縮されていないバージョンのアーカイブをディスクに保存しません)。
例
これは、さまざまな形式で圧縮されたLinuxカーネルソースツリーです。
$ ls --block-size=1 -sS1
666210304 linux-4.6.tar
173592576 linux-4.6.zip
97038336 linux-4.6.7z
89468928 linux-4.6.tar.xz
まず、上記のように、7zとzipはわずかに異なります。これらはそこに少数のシンボリックリンクを格納できず、ほとんどのメタデータが欠落しているためです。
次に、システムキャッシュをフラッシュした後、コンテンツを一覧表示するタイミングをいくつか示します。
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time tar tvf linux-4.6.tar > /dev/null
tar tvf linux-4.6.tar > /dev/null 0.56s user 0.47s system 13% cpu 7.428 total
$ time tar tvf linux-4.6.tar.xz > /dev/null
tar tvf linux-4.6.tar.xz > /dev/null 8.10s user 0.52s system 118% cpu 7.297 total
$ time unzip -v linux-4.6.zip > /dev/null
unzip -v linux-4.6.zip > /dev/null 0.16s user 0.08s system 86% cpu 0.282 total
$ time 7z l linux-4.6.7z > /dev/null
7z l linux-4.6.7z > /dev/null 0.51s user 0.15s system 89% cpu 0.739 total
ディスクからこれらの余分なメガバイトを読み取るには、小さいファイルを読み取って解凍するよりも時間がかかるため、この7年前のPCでのtar.xz
ファイルよりもファイルのリストの方が速いことに気づくでしょう.tar
。
次に、7zまたはzipを使用してアーカイブを一覧表示する方が高速ですが、前述のように問題ありません。アーカイブと一緒にファイルリストを保存することで簡単に回避できます。
$ tar tvf linux-4.6.tar.xz | xz > linux-4.6.tar.xz.list.xz
$ ls --block-size=1 -sS1 linux-4.6.tar.xz.list.xz
434176 linux-4.6.tar.xz.list.xz
$ time xzcat linux-4.6.tar.xz.list.xz > /dev/null
xzcat linux-4.6.tar.xz.list.xz > /dev/null 0.05s user 0.00s system 99% cpu 0.051 total
キャッシュをドロップした後でも、7zまたはzipよりも高速です。また、アーカイブとそのインデックスの累積サイズがzipまたは7zアーカイブよりも小さいことに気付くでしょう。
または、pixz
インデックス形式を使用します。
$ xzcat linux-4.6.tar.xz | pixz -9 > linux-4.6.tar.pixz
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz
89841664 linux-4.6.tar.pixz
$ echo 3 | sudo tee /proc/sys/vm/drop_caches
3
$ time pixz -l linux-4.6.tar.pixz > /dev/null
pixz -l linux-4.6.tar.pixz > /dev/null 0.04s user 0.01s system 57% cpu 0.087 total
ここで、アーカイブの個々の要素を抽出するために、tarアーカイブの最悪のシナリオは、最後の要素にアクセスするときです。
$ xzcat linux-4.6.tar.xz.list.xz|tail -1
-rw-rw-r-- root/root 5976 2016-05-15 23:43 linux-4.6/virt/lib/irqbypass.c
$ time tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c | wc
257 638 5976
tar xOf linux-4.6.tar.xz linux-4.6/virt/lib/irqbypass.c 7.27s user 1.13s system 115% cpu 7.279 total
wc 0.00s user 0.00s system 0% cpu 7.279 total
アーカイブ全体を読み取る(そして圧縮解除する)必要があるため、これはかなり悪いことです。と比べて:
$ time unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c | wc
257 638 5976
unzip -p linux-4.6.zip linux-4.6/virt/lib/irqbypass.c 0.02s user 0.01s system 19% cpu 0.119 total
wc 0.00s user 0.00s system 1% cpu 0.119 total
私のバージョンの7zはランダムアクセスを実行できないようです。そのため、次のものよりもさらに悪いようですtar.xz
。
$ time 7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null | wc
257 638 5976
7z e -so linux-4.6.7z linux-4.6/virt/lib/irqbypass.c 2> /dev/null 7.28s user 0.12s system 89% cpu 8.300 total
wc 0.00s user 0.00s system 0% cpu 8.299 total
これで、pixz
以前のバージョンから生成されたものがあるので、
$ time pixz < linux-4.6.tar.pixz -x linux-4.6/virt/lib/irqbypass.c | tar xOf - | wc
257 638 5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz 1.37s user 0.06s system 84% cpu 1.687 total
tar xOf - 0.00s user 0.01s system 0% cpu 1.693 total
wc 0.00s user 0.00s system 0% cpu 1.688 total
アーカイブには大きなブロックがほとんど含まれていないため、高速ですが比較的低速です。
$ pixz -tl linux-4.6.tar.pixz
17648865 / 134217728
15407945 / 134217728
18275381 / 134217728
19674475 / 134217728
18493914 / 129333248
336945 / 2958887
したがってpixz
、最大19 MBの大きなデータチャンクを読み取り、解凍する必要があります。
アーカイブを小さくすることでランダムアクセスを高速化できます(そしてディスク容量を少し犠牲にします):
$ pixz -f0.25 -9 < linux-4.6.tar > linux-4.6.tar.pixz2
$ ls --block-size=1 -sS1 linux-4.6.tar.pixz2
93745152 linux-4.6.tar.pixz2
$ time pixz < linux-4.6.tar.pixz2 -x linux-4.6/virt/lib/irqbypass.c | tar xOf - | wc
257 638 5976
pixz -x linux-4.6/virt/lib/irqbypass.c < linux-4.6.tar.pixz2 0.17s user 0.02s system 98% cpu 0.189 total
tar xOf - 0.00s user 0.00s system 1% cpu 0.188 total
wc 0.00s user 0.00s system 0% cpu 0.187 total