web-dev-qa-db-ja.com

Zipが、同じコンテンツを持つ複数のファイルよりも小さい単一のファイルを圧縮できるのはなぜですか。

10,000個のXMLファイルがあるとします。今、私はそれらを友達に送りたいとします。それらを送る前に、私はそれらを圧縮したいです。

方法1:圧縮しない

結果:

Resulting Size: 62 MB
Percent of initial size: 100%

方法2:すべてのファイルを圧縮して10,000 xmlファイルを送信する

コマンド:

for x in $(ls -1) ;  do   echo $x ; Zip "$x.Zip" $x ; done

結果:

Resulting Size: 13 MB
Percent of initial size: 20%

方法3:10,000 xmlファイルを含む単一のZipを作成する

コマンド:

Zip all.Zip $(ls -1)

結果:

Resulting Size: 12 MB
Percent of initial size: 19%

方法4:ファイルを1つのファイルに連結して圧縮する

コマンド:

cat *.xml > oneFile.txt ; Zip oneFile.Zip oneFile.txt

結果:

Resulting Size: 2 MB
Percent of initial size: 3%

質問:

  • 1つのファイルを圧縮するだけで、劇的に良い結果が得られるのはなぜですか?
  • 方法2より方法3を使用した方が劇的に良い結果が得られると期待していましたが、そうではありませんでした。どうして?
  • この動作はZipに固有のものですか? gzipを使用しようとすると、異なる結果が得られますか?

追加情報:

$ Zip --version
Copyright (c) 1990-2008 Info-Zip - Type 'Zip "-L"' for software license.
This is Zip 3.0 (July 5th 2008), by Info-Zip.
Currently maintained by E. Gordon.  Please send bug reports to
the authors using the web page at www.info-Zip.org; see README for details.

Latest sources and executables are at ftp://ftp.info-Zip.org/pub/infozip,
as of above date; see http://www.info-Zip.org/ for other sites.

Compiled with gcc 4.4.4 20100525 (Red Hat 4.4.4-5) for Unix (Linux ELF) on Nov 11 2010.

Zip special compilation options:
    USE_EF_UT_TIME       (store Universal Time)
    SYMLINK_SUPPORT      (symbolic links supported)
    LARGE_FILE_SUPPORT   (can read and write large files on file system)
    Zip64_SUPPORT        (use Zip64 to store large files in archives)
    UNICODE_SUPPORT      (store and read UTF-8 Unicode paths)
    STORE_UNIX_UIDs_GIDs (store UID/GID sizes/values using new extra field)
    UIDGID_NOT_16BIT     (old Unix 16-bit UID/GID extra field not used)
    [encryption, version 2.91 of 05 Jan 2007] (modified for Zip 3)

編集:メタデータ

1つの答えは、違いはZipに格納されているシステムメタデータであることを示唆しています。私はこれが当てはまるとは思わない。テストするために、次のことを行いました。

for x in $(seq 10000) ; do touch $x ; done
Zip allZip $(ls -1)

結果のZipは1.4MBです。これは、説明できないスペースがまだ約10 MBあることを意味します。

125

Zipは圧縮時に各ファイルの内容を別々に扱います。各ファイルには独自の圧縮ストリームがあります。繰り返しセクションを識別するための圧縮アルゴリズム(通常 DEFLATE )内でのサポートがあります。ただし、Zipにはファイル間の冗長性を見つけるためのサポートはありません。

そのため、コンテンツが複数のファイルにある場合は、余分なスペースが非常に多くなります。同じ圧縮ストリームをファイルに複数回入れます。

128
Alan Shutko

Zip圧縮は、圧縮されるデータ内の繰り返しパターンに基づいており、より多くのより長いパターンを見つけて使用することができるため、ファイルが長ければ長いほど圧縮率は向上します。

簡単に言うと、1つのファイルを圧縮する場合、(短い)コードを(長い)パターンにマップする辞書は、結果として得られる各Zipファイルに必ず含まれています。 1つの長いファイルをZip圧縮すると、辞書は「再利用」され、すべてのコンテンツにわたってさらに効果的になります。

あなたのファイルが(テキストがいつもそうであるように)少しでも似ているならば、「辞書」の再利用は非常に効率的になり、そして結果ははるかに小さい合計Zipになります。

48
Aganju

Zipでは、各ファイルは別々に圧縮されています。その逆は '固体圧縮'です。つまり、ファイルはまとめて圧縮されます。 7-ZipとRarはデフォルトでベタ圧縮を使用します。 GzipとBzip2は複数のファイルを圧縮できないため、Tarが最初に使用され、ソリッド圧縮と同じ効果があります。

ファイルが一緒に圧縮されている場合、xmlファイルは似たような構造を持ち、おそらく似たような内容を持つため、圧縮率は高くなります。

たとえば、ファイルに文字列"<content><element name="が含まれていて、コンプレッサが別のファイルでその文字列をすでに見つけた場合、コンプレッサがその文字列の最初の出現を 'solid compression'で使用しないファイルはもっと大きいリテラルとして記録されます。

43
ggf31416

Zipはファイルの内容を保存するだけでなく、所有しているユーザーID、アクセス許可、作成および変更時刻などのファイルメタデータも保存します。ファイルが1つある場合は、メタデータが1セットあります。 10,000個のファイルがある場合は、10,000個のメタデータセットがあります。

9
Mike Scott

OPが見逃したオプションは、圧縮をオフにした状態ですべてのファイルをZip圧縮し、次に圧縮率を最大に設定してZipを圧縮することです。これは、* nix .tar.Z、.tar.gz、.tar.bzなどの圧縮アーカイブの動作を、ファイルの境界を越えた冗長性(Zipアルゴリズムを単一のアルゴリズムで実行した場合には不可能)を利用して大まかにエミュレートします。パス)。これにより、個々のXMLファイルを後で抽出することができますが、圧縮は最大化されます。欠点は、抽出処理に余分な手順が必要で、通常の.Zipに必要な場合よりもはるかに多くのディスク容量が一時的に使用されることです。

TarファミリーをWindowsに拡張するための7-Zipのようなフリーツールの普及に伴い、Linux、OS X、BSDはすべてそうであるように、.tar.gzや.tar.bzなどを使わない理由は全くありません。それらを操作するためのネイティブツール。

7
Monty Harder

Zip圧縮形式は、各ファイルを別々に格納して圧縮します。ファイル内でのみ、ファイル間の繰り返しを利用しません。

ファイルを連結すると、Zipはすべてのファイルで繰り返しを利用できるようになり、結果として劇的に圧縮率が向上します。

たとえば、各XMLファイルに特定のヘッダーがあるとします。そのヘッダーは各ファイルで一度だけ現れますが、他の多くのファイルでもほぼ同じように繰り返されます。方法2と3ではZipは圧縮できませんでしたが、方法4では圧縮できました。

5
BonsaiOak

Mike Scottは、メタデータの隣に、圧縮アルゴリズムにもオーバーヘッドがあると述べました。

個々の小さなファイルをまとめて圧縮するときは、1つの圧縮ブロックを埋めるだけで済むので、それらを圧縮できるようになることは非常に幸運なことです。単一のモノリシックブロックを圧縮するとき、システムは、個々のファイルの「境界」(Wordの改善の欠如)を無視して、データをそのアルゴリズムにストリーミングし続けることができます。

また、ASCIIは高い圧縮率を持つことが知られています。 xmlはしばしば非常に反復的であり、メタデータをxmlコンテンツのように簡単には圧縮できない大きなデータの塊にします。

最後に、メモリが適切に機能する場合、Zipは辞書エンコーディングのようなものを使用します。これはASCIIファイルに特に効果的であり、XMLにはその繰り返し性によりさらに効果的です。

データ圧縮の説明: http://mattmahoney.net/dc/dce.html

4
GapWim

このXMLを考えてください。

<root>
  <element id="1" />
  <element id="2" /> 
  <other id="3" />
  ...
</root>

XMLは非常に反復的な構造を持ち、Zipはこれらの反復を利用してパターンの出現回数が多くなり、圧縮時に使用する辞書が少なくなる辞書を作成します。より多くの繰り返しパターンを格納するためのビットおよびより少ない繰り返しパターンを格納するためのより多くのビット

これらのファイルを連結すると、ソースファイル(Zipのソース)は大きくなりますが、さらに多くの繰り返しパターンが含まれます。 XMLの退屈な構造の分散は、大きなファイル全体で償却されているため、Zipにチャンスが与えられます。少ないビット数でそれらのパターンを格納する。

異なるXMLを1つのファイルに結合した場合、それらのファイルのタグ名が完全に異なる場合でも、圧縮アルゴリズムによって、全体で最も良いパターンの分布が検出されます。ファイルごとではなく、すべてのファイル。

最終的に、圧縮アルゴリズムは最良の繰り返しパターン分布を見つけました。

3
rnrneverdies