Zip neden tek bir dosyayı aynı içeriğe sahip birden çok dosyadan daha küçük sıkıştırabilir?


126

10.000 XML dosyam olduğunu varsayalım. Şimdi onları bir arkadaşıma göndermek istediğimi varsayalım. Göndermeden önce onları sıkıştırmak istiyorum.

Yöntem 1: Onları sıkıştırmayın

Sonuçlar:

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

Yöntem 2: Her dosyayı sıkıştırın ve ona 10.000 xml dosya gönderin.

Komut:

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

Sonuçlar:

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

Yöntem 3: 10.000 xml dosya içeren tek bir zip oluşturun

Komut:

zip all.zip $(ls -1)

Sonuçlar:

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

Yöntem 4: Dosyaları tek bir dosyada birleştirin ve sıkıştırın

Komut:

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

Sonuçlar:

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

Sorular:

  • Tek bir dosyayı sıkıştırırken neden bu kadar önemli sonuçlar elde ediyorum?
  • Yöntem 2'yi kullanarak yöntem 2'den çok daha iyi sonuçlar almayı bekliyordum, ama almadım. Neden?
  • Bu davranış belirli zipmi? Kullanmayı gzipdenersem farklı sonuçlar alır mıyım?

İlave bilgi:

$ 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)

Düzenleme: Meta veri

Bir cevap, farkın zip'te depolanan sistem meta verileri olduğunu göstermektedir. Bunun olabileceğini sanmıyorum. Test etmek için aşağıdakileri yaptım:

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

Ortaya çıkan zip 1.4 MB'dir. Bu, hala ~ 10 MB açıklanamayan alan olduğu anlamına gelir.


34
Yanılmıyorsam, bu .tar.gzsadece insanların tüm dizini sıkıştırmak yerine tersine çevirmelerine neden olan olaydır .
corsiKa

18
Bir benzer soru zaten tl istendi; dr katı 7zip arşivleri kullanabilirsiniz.
Dmitry Grigoryev

3
@sixtyfootersdude Bazı cevapların doğrulanması için bir test olarak, yöntem 3'te üretilen zip sıkıştırmasını deneyebilir misiniz? Bunun dosya boyutunu yöntem 4 ile karşılaştırılabilir bir şeye indirgeyeceğinden şüpheliyim.
Travis

7
Yerine $(ls -1), sadece kullanmak *: for x in *; zip all.zip *
muru

4
ZIP ile sağlam bir sıkıştırma yapmak istiyorsanız, işte bir geçici çözüm: ilk önce tüm dosyalarınızı içeren sıkıştırılmamış bir ZIP oluşturun. Ardından, bu ZIP’i başka bir sıkıştırılmış ZIP’e yerleştirin.
user20574,

Yanıtlar:


129

Sıkıştırma sırasında, Zip her dosyanın içeriğini ayrı olarak ele alır. Her dosyanın kendine ait sıkıştırılmış akışı olacaktır. Sıkıştırma algoritması (genellikle DEFLATE ) içinde tekrarlanan bölümleri tanımlamak için destek var . Ancak, dosyalar arasında artıklık bulma konusunda Zip desteği yoktur.

Bu nedenle, içerik birden fazla dosyadayken bu kadar fazla alan var: aynı sıkıştırılmış akışı dosyaya birden çok kez yerleştiriyor.


9
Ayrıca bazı sıkıştırma araçlarının dosyaları ayrı ayrı veya tek bir varlık olarak sıkıştırma seçeneği de sağlamasının nedeni budur. (Genelde bu, aynı zamanda yalnızca tek bir dosyayı görüntülemek istiyorsanız, arşivden daha fazla sıkıştırmanız gerektiği anlamına gelse de.)
JAB

28
@JAB: 7z ve rar gibi sıkıştırma araçları, daha büyük sıkıştırma akışlarına yerleştirmek üzere birden fazla dosyayı başa koymak için "katı" arşivini kullanır. 64MiB gibi orta boyutta bir yığın boyutunda, tek bir dosyaya rasgele erişim, içinde bulunduğu sıkıştırma bloğunun başlangıcından itibaren 64MiB'a kadar verilerin sıkıştırılmasını gerektirebilir. Şekil 7z, zip üzerinde bir başka avantaj olan daha etkili (ancak sıkıştırması daha yavaş) LZMA sıkıştırma şemasını kullanabilir.
Peter Cordes

there is no support in Zip to find redundancy between filesZip dosyası özelliklerinde olduğunu mu söylüyorsun ?
altmış

6
@sixtyfootersdude DEFLATE gibi birçok sıkıştırma algoritması bir akış olarak çalışır. Akışın bir bölümünü açmak için yeterli bilgiyi geri kazanmak için, akışın tamamını o noktaya kadar işlemeniz gerekir. Dosyalar arasında artıklık bulmaya çalıştılarsa, sonuncusuna ulaşmak için 1000 dosyanın hepsini açmanız gerekir. Aslında, genellikle tgz böyle çalışır. Ancak, zip, tek tek dosyaları ayıklamanıza izin vermek için tasarlanmıştır. tgz ya hep ya hiç ya hiç bir şey olacak şekilde tasarlanmıştır
Cort Ammon

1
@sixtyfootersdude - bu doğru. Cort'dan alıntı yapmak için: pkzip özellikleri çalışma çapraz dosyasını desteklemiyor. Yapmışlarsa, bir dosyayı ayıklamak tüm arşivin (ve her dosyanın) çıkarılmasını gerektirebilir.
James Snell

48

ZIP sıkıştırması, sıkıştırılacak verilerdeki yinelenen kalıplara dayanır ve daha uzun kalıplar bulunup kullanılabildiğinden, sıkıştırma, dosya ne kadar uzun olursa o kadar iyi olur.

Basitleştirilmiş, bir dosyayı sıkıştırırsanız, (kısa) kodları (daha uzun) kalıplarla eşleştiren sözlüğün mutlaka sonuçta elde edilen her zip dosyasında bulunması gerekir; Uzun bir dosyayı sıkıştırırsanız, sözlük 'yeniden kullanılır' ve tüm içeriklerde daha etkili bir şekilde büyür.

Dosyalarınız biraz benzerse (metin her zaman olduğu gibi), 'sözlüğün' tekrar kullanılması çok verimli olur ve sonuç daha küçük bir toplam zip olur.


3
ZIP hem arşivleme hem de sıkıştırma yapar. Bu, aynı ZIP dosyasında olsalar bile ZIP'in her dosyayı ayrı ayrı sıkıştırdığı anlamına mı geliyor?
gerrit

2
Tek bir dosyayı kaldırdığınızı hayal edin, başka bir yarım saatin geri kalanını yeni bir 'sözlük' ile yeniden sıkıştırmak için başka bir yarım saat harcamasını istemezsiniz. - ayrıca, muhtemelen farklı dosyaların çok farklı 'sözlükler' gerektirdiği varsayılmaktadır.
Aganju

2
Neden olması gerektiğini anlamıyorum. Unix araçlarıyla, önce tar ile bir dosyayı arşivler, sonra gzip / bz2 / lzma ile sıkıştırırdım. Sıkıştırma algoritması, arşivde kaç dosyanın kodlandığını önemsemez. Ayrıca, sıkıştırılmış bir arşivden tek bir dosyayı kaldırmak gerçekten ne kadar yaygındır? Bunu daha önce yaptığımı sanmıyorum.
gerrit

4
Katılmıyorum ve bu muhtemelen iyi bir yoldur. ZIP tasarlamadım ya da yazmadım. Sadece ne yaptığını söyledim ...
Aganju

16
@gerrit Kendi problemleri var. Zip, arşivdeki herhangi bir dosyaya hızlıca erişmenize izin vermek için tasarlanmıştır - 100 GiB UHA arşivinden tek bir dosyayı açmayı deneyin; neden bu şekilde seçtiklerini göreceksiniz. Aynı zamanda eklemek için de tasarlanmıştır - yedekleme zip'inizi alabilir ve gerektiğinde dosyaları eklemeye (veya değiştirmeye) devam edebilirsiniz. Bunların hepsi arşivleri kullanırken çok yardımcı oluyor. Trade-off (ki çok benzer dosyaları sıkıştırarak eğer ki değil tüm bu ortak), bu arşiv boyutunu azaltmak için benzerlikler istismar edemez.
Luaan

43

Zip'de her dosya ayrı ayrı sıkıştırılır. Bunun tersi 'katı sıkıştırma', yani dosyalar birlikte sıkıştırılıyor. 7-zip ve Rar varsayılan olarak katı sıkıştırma kullanır. Gzip ve Bzip2 birden fazla dosyayı sıkıştıramadığından, önce Tar kullanılır, katı sıkıştırma ile aynı etkiye sahiptir.

Xml dosyası benzer yapıya sahip olduğundan ve dosyalar birlikte sıkıştırılırsa büyük olasılıkla benzer içeriğe sahip olduklarından, sıkıştırma daha yüksek olacaktır.

Örneğin, bir dosya dizeyi içeriyorsa "<content><element name="ve kompresör zaten bu dizeyi başka bir dosyada bulmuşsa, önceki dizinin yerine küçük bir işaretçi koyar, eğer kompresör dizede ilk sırada 'katı sıkıştırma' kullanmazsa dosya daha büyük olan bir hazır bilgi olarak kaydedilecektir.


9

Zip, sadece dosyanın içeriğini kaydetmez, aynı zamanda sahip olan kullanıcı kimliği, izinler, oluşturma ve değiştirme zamanları gibi dosya meta verilerini de depolar. Bir dosyanız varsa, bir meta verilere sahip olursunuz; 10.000 dosyanız varsa, 10.000 meta veri kümeniz vardır.


3
İyi nokta, ancak sistem meta verileri yalnızca 1.4 MB alan kaplıyor. Düzenlemeye bak.
altmış

1
Zip algoritmasına aşina değilim, ancak meta veriler yalnızca dosya bilgileri değil, aynı zamanda büyüklük ve sözlük gibi şeyler, belki de karakterlerin dağıtılmasıyla ilgili bilgiler. Boş olmayan bir metin dosyasındaki bir sözlük sıfır olmayacaktır. Muhtemelen xml dosyalarınızda meta verilerin boş dosyalarınızdan daha büyük olduğunu görmenizin nedeni budur.
Ben Richards

Bu benim ilk düşüncemdi. Zip-Dosya Başlığı Bilgisi
WernerCD

Bu sadece 2 ile 3 arasındaki farkı açıklar - 4 değil.
Luaan

@Luaan Hayır, hem 2 hem de 3'te, tüm 10.000 dosyanın meta verileri zip dosyasına veya dosyalara dahil edilmiştir, bu nedenle toplam dosya boyutu neredeyse aynı boyuttadır. 4'te, bir dosya için yalnızca meta veriler var ve zip dosyası çok daha küçük.
Mike Scott,

7

OP tarafından kaçırılan bir seçenek, tüm dosyaları sıkıştırma kapalıyken birlikte sıkıştırmak ve ardından ortaya çıkan sıkıştırmayı maksimum olarak ayarlanmış sıkıştırmayla sıkıştırmaktır. Bu, kabaca, * nix. geçmek). Bu, bağımsız XML dosyalarının daha sonra ayıklanmasını sağlar, ancak sıkıştırmayı en üst düzeye çıkarır. Dezavantajı ise, çıkarma işleminin normal bir .zip için gerekenden geçici olarak çok daha fazla disk alanı kullanarak, fazladan bir adım gerektirmesidir.

Katran ailesini Windows'a genişletmek için 7-Zip gibi ücretsiz araçların yaygınlığı sayesinde, Linux, OS X ve BSD'lerin hepsinde olduğu gibi .tar.gz veya .tar.bz vb. onları işlemek için yerel araçlar.


gzip ve bzip2 daha da kötüye gidebilir çünkü akılda akışları sıkıştırarak tasarlanırlar, bu nedenle sıkıştırılacak verilerin tümü bilinmeden önce sıkıştırılmış veri göndermeye başlamak zorunda kalacaklar.
rackandboneman

@rackandboneman: Sıkıştırma sırasında kullanmak istediğiniz hafıza miktarından daha büyük dosyaları sıkıştırırken yapmanız gereken tradeoff. (Ve ayrıca, global olarak en uygun olanı bulmak için gereken CPU zamanı miktarı çok fazla olurdu.) Büyük bir sıkıştırma sözlüğü, dekompresyon için gereken belleği de artırabilir . Bu, LZMA ( xz/ 7-zip) için bir seçenektir . Her neyse, uyarlanabilir sözlükler göründükten sonra kalıpları alabilir. İlk 32k'ye dayanan statik bir kodlama sistemi kurması pek mümkün değil. Bu yüzden gzip emmez.
Peter Cordes

Zip formatı ile kalmak gerekirse bu gerçekten "hile" seviyorum. "7-zip kullanmamak için bir neden yok" una katılmıyorum - teknik olmayan bir arkadaşıma dosya gönderiyorsam, kolayca açabileceklerinden emin olmak istiyorum. Bir iş müşterisine gönderiyorum, hatta daha fazlası.
Wowfunhappy

5

Zip sıkıştırma formatı her dosyayı ayrı olarak saklar ve sıkıştırır. Yalnızca bir dosya içinde, dosyalar arasında tekrarı kullanmaz.

Dosyayı birleştirmek, zipin tüm dosyalardaki tekrarlardan faydalanmasına izin vererek, daha fazla sıkıştırma sağlar.

Örneğin, her XML dosyasının belirli bir başlığı olduğunu söyleyin. Bu başlık her dosyada yalnızca bir kez oluşur, ancak diğer birçok dosyada neredeyse aynı şekilde tekrarlanır. Yöntem 2 ve 3'te zip bunun için sıkıştırılamadı, ancak yöntem 4'te olabilir.


3
Bunun daha önce 5 saat önce yayınlanan ilk 3 cevaptan birinden ne farkı var?
Xen2050

1
@ Xen2050 Çok fazla fark yok, sadece daha net açıklayabileceğimi düşündüm.
BonsaiOak

1
@BonsaiOak - sonra doğru cevap için bir yorum ekleyin ya da yeterli bilginiz varsa düzenleyin. Aksi halde yorumunuz netlik eklerse, başka biri bunu alabilir ve yayını yine de düzenleyebilir.
AdamV

@AdamV Amacınızı anlıyorum. Cevabım şu anda faydalı bir bilgi eklemiyor, ancak yazarken yazmama rağmen. İlk cevabın altında zaten uygun yorumlar var, bu yüzden onları da ekleyeceğim noktayı göremiyorum. Cevabımı kapatmam gerektiğini mi söylüyorsun? Açık bırakmanın ne zararı var?
BonsaiOak

4

Mike Scott’un üstlendiği meta verilerin yanında, sıkıştırma algoritmasında da ek yükü var.

Bireysel küçük dosyaları bir demet sıkıştırırken, sadece bir sıkıştırma bloğunu doldurduğu için onları sıkıştırabilmeniz için çok şanslı olmalısınız. Tek bir monolitik bloğu sıkıştırırken, sistem kendi dosyalarının 'sınırlarını' (daha iyi bir kelime eksikliği için) yok sayarak algoritmasına veri akışına devam edebilir.

Ayrıca ASCII'nin yüksek bir sıkıştırma faktörüne sahip olduğu bilinmektedir. Ayrıca, xml, meta verileri, xml içeriği kadar kolay sıkıştırılamayan büyük bir veri yığını haline getirir.

Son olarak, eğer bellek doğru kullanılırsa, zip özellikle tekrarlanan dosyalar nedeniyle özellikle ascii dosyalarında ve hatta XML'de etkili olan sözlük kodlaması gibi bir şey kullanır.

Açıklanan Veri Sıkıştırma: http://mattmahoney.net/dc/dce.html


3

Bu XML düşünün:

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

XML Posta olan bir sözlük oluşturmak için bu tekrar yararlanır, bir çok tekrarlanan yapıya sahip model daha fazla örneği vardır ve sıkıştırılırken daha sonra, daha az bit daha tekrarlandı depolamak için kullandığı kalıpları daha az tekrar saklamak ve daha fazla bit modeli .

Ne zaman bağlamak bu dosyaları, kaynak dosya (zip için kaynak) büyük ama çok daha içeriyor tekrarlanan desenleri bir XML sıkıcı yapıların de dağıtım çünkü amorti olanlar saklamak için ZIP şansı veren büyük bütün dosyada desen daha az bit kullanmak.

Şimdi, farklı XML'yi tek bir dosyada birleştirirseniz, bu dosyalar tamamen farklı etiket adlarına sahip olsalar bile, sıkıştırma algoritması tüm dosyalar arasında en iyi kalıp dağılımını bulacaktır, dosyaya göre değil.

Sonunda sıkıştırma algoritması en iyi tekrarlanan model dağılımını buldu.


-1

7-Zip cevabına ek olarak, o kadar iyi olmayan ancak herhangi bir nedenle 7-Zip kullanmak istemiyorsanız denemeye değer olan başka bir yaklaşım daha var:

Zip dosyasını sıkıştırın. Şimdi, normalde bir zip dosyası sıkıştırılamaz ancak çok fazla aynı dosya içerdiğinde kompresör bu fazlalığı bulabilir ve sıkıştırabilir. Ayrıca fazlalık olmayan çok sayıda dosyayla çalışırken de küçük bir kazanç gördüğümü unutmayın. Gerçekten boyutu önemsiyorsanız, zip içinde çok fazla dosya varsa denemeye değer.


Bu sadece yukarıda bahsettiğim gibi sıkıştırma kapalı ilk zip yaparsanız çalışır.
Monty Harder

@MontyHarder Sıkıştırma açıkken çalıştığını gördüm.
Loren Pechtel
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.