web-dev-qa-db-ja.com

アーカイブファイルリストを即座に印刷(アーカイブ全体を解凍せずに)

.tar.gzアーカイブの問題は、アーカイブのコンテンツを一覧表示しようとすると、コンピュータが実際に圧縮解除するため、ファイルが大きい場合に非常に長い時間がかかることです。

.7z.rar.Zipなどの他のファイル形式には、この問題はありません。それらの内容をリストすることはほんの一瞬です。

私の素朴な意見では、これは.tar.gzアーカイブ形式の大きな欠点です。

だから私は実際に2つの質問があります:

  1. この欠点にもかかわらず、なぜ人々は.tar.gzをそれほど多く使用するのですか?
  2. 「インスタントコンテンツリスト」機能が必要な場合、どのような選択肢がありますか(他のソフトウェアまたはツールを意味します)。
10
David Dai

ここにはトレードオフがあることを理解することが重要です。

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などでインデックスを作成する必要があります。そのインデックスは、ファイルの最初(ストリームではなく通常のファイルにのみ書き込むことができます)または最後に保存できます。つまり、アーカイバは最後に印刷する前にすべてのアーカイブメンバーを覚えておく必要があります。また、切り捨てられたアーカイブは復元できない可能性があります。

これは、アーカイブメンバーを個別に圧縮する必要があることも意味します。これは、特に小さなファイルが多い場合、圧縮率がはるかに低くなることを意味します。

Zipのような形式のもう1つの欠点は、アーカイブが圧縮にリンクされているため、圧縮アルゴリズムを選択できないことです。 tarアーカイブがcompresstar.Z)、次にgzipbzip2xzのいずれで圧縮されていたかをご覧ください。新しいより高性能な圧縮アルゴリズムが考案されました。暗号化についても同様です。今日、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ファイルの末尾にアーカイブの各メンバーの先頭のインデックスも追加します。

したがって、シーク可能なファイルの場合、pixzで圧縮されていれば、tarアーカイブの内容のリストを(メタデータなしで)即座に取得できるだけでなく、

pixz -l file.tar.xz

ただし、アーカイブ全体を読み取らずに、個々の要素を抽出することもできます。

pixz -x archive/member.txt < file.tar.xz | tar xpf -

さて、なぜ7zZipのようなものがUnixでめったに使用されないのかについては、ほとんどがUnixファイルをアーカイブできないためです。これらは他のオペレーティングシステム用に設計されています。これらを使用してデータを忠実にバックアップすることはできません。所有者(IDと名前)、許可などのメタデータを保存できません。シンボリックリンク、デバイス、FIFOなどを保存できません。ハードリンクに関する情報や、拡張属性やACLなどの他のメタデータ情報を保存できません。

それらの一部は、任意の名前のメンバーを保存することさえできません(一部は、バックスラッシュ、改行、コロン、または非ASCIIファイル名で窒息します)(一部のtar形式にも制限があります)。

Tgz/tar.xzファイルをディスクに解凍しないでください!

明らかでない場合は、tgzまたはtar.bz2tar.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は、最大19MBのデータのチャンク(最大1つ)を読み取って圧縮解除する必要があります。

アーカイブを小さくすることでランダムアクセスを高速化することができます(そしてディスク容量を少し犠牲にします):

$ 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
18
  1. なぜ人々はこの欠点にもかかわらずそれをそんなに使うのですか?

物事が効率的に実行されているときよりも、物事が壊れたときの方が、企業や学術の管理者に気付かれることがよくあります。そのような環境は実験への恐れを生み、そして 新規性を軽蔑する です。

  1. 「インスタントコンテンツリスト」機能が必要な場合、どのような選択肢がありますか(他のソフトウェア/ツールを意味します)。

dar[〜#〜] d [〜#〜]iskArchiver)は、tarに似た機能に加えて、圧縮アーカイブの高速ランダムアクセス、カタログ作成、インデックス作成、「インスタントコンテンツリスト」などの拡張機能...

参照: アーカイブ内のランダムアクセスを適切にサポートする圧縮形式?

3
agc