133 votes

Pourquoi Zip est-il capable de compresser un seul fichier plus petit que plusieurs fichiers ayant le même contenu ?

Supposons que je possède 10 000 fichiers XML. Supposons maintenant que je veuille les envoyer à un ami. Avant de les envoyer, j'aimerais les compresser.

Méthode 1 : Ne pas les compresser

Résultats :

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

Méthode 2 : zippez chaque fichier et envoyez-lui 10 000 fichiers xml.

Commandement :

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

Résultats :

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

Méthode 3 : Créer un seul zip contenant 10 000 fichiers xml

Commandement :

zip all.zip $(ls -1)

Résultats :

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

Méthode 4 : Concaténer les fichiers en un seul fichier et le zipper.

Commandement :

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

Résultats :

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

Questions :

  • Pourquoi est-ce que j'obtiens de si bons résultats lorsque je ne fais que compresser un seul fichier ?
  • Je m'attendais à obtenir de bien meilleurs résultats en utilisant la méthode 3 que la méthode 2, mais ce n'est pas le cas. Pourquoi ?
  • Ce comportement est-il spécifique à zip ? Si j'ai essayé d'utiliser gzip obtiendrais-je des résultats différents ?

Informations supplémentaires :

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

Editer : Méta-données

Une réponse suggère que la différence réside dans les métadonnées du système qui sont stockées dans le zip. Je ne pense pas que cela puisse être le cas. Pour tester, j'ai fait ce qui suit :

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

Le zip résultant est de 1,4 Mo. Cela signifie qu'il y a encore ~10 Mo d'espace inexpliqué.

0 votes

Je ne suis pas familier avec le fonctionnement interne du programme zip, mais mon hypothèse initiale est que les méthodes 2 et 3 font essentiellement la même chose, sauf que zip combine les fichiers zippés individuels en une seule archive à la fin, ce qui expliquerait pourquoi les méthodes 3 et 4 sont aussi différentes.

36 votes

Si je ne me trompe pas, c'est ce phénomène qui fait que les gens font .tar.gz plutôt que de simplement compresser le répertoire entier.

0 votes

@corsiKlauseHoHoHo - Je parie que vous avez raison. Alors vous ne faites que zipper un seul fichier. Ce qui a probablement le même effet... Très intéressant

5voto

BonsaiOak Points 158

Le format de compression zip stocke et compresse chaque fichier séparément. Il ne tire pas parti des répétitions entre les fichiers, mais uniquement à l'intérieur d'un fichier.

La concaténation du fichier permet à zip de tirer parti des répétitions dans tous les fichiers, ce qui permet une compression nettement plus importante.

Par exemple, disons que chaque fichier XML possède un certain en-tête. Cet en-tête n'apparaît qu'une seule fois dans chaque fichier mais est répété presque à l'identique dans de nombreux autres fichiers. Dans les méthodes 2 et 3, zip ne pourrait pas compresser pour cela, mais dans la méthode 4, il le pourrait.

3 votes

Quelle est la différence avec l'une des trois meilleures réponses déjà postées 5 heures plus tôt ?

1 votes

@Xen2050 Pas beaucoup de différence, je pensais juste pouvoir l'expliquer plus clairement.

1 votes

@BonsaiOak - puis ajoutez un commentaire à la bonne réponse ou éditez si vous avez suffisamment de représentants. Si ce n'est pas le cas, mais que votre commentaire apporte de la clarté, quelqu'un d'autre pourrait s'en rendre compte et modifier le message de toute façon.

4voto

GapWim Points 158

Outre les métadonnées, Mike Scott a mentionné que l'algorithme de compression entraîne également des frais généraux.

Lors de la compression d'un ensemble de petits fichiers individuels, il faut être très chanceux pour pouvoir les compresser de manière à ce qu'ils remplissent un seul bloc de compression. Lors de la compression d'un seul bloc monolithique, le système peut simplement continuer à transmettre des données à son algorithme, en ignorant les "limites" (faute d'un meilleur terme) des fichiers individuels.

De plus, le format ASCII est connu pour avoir un facteur de compression élevé. De plus, le format xml est souvent très répétitif, ce qui fait que les métadonnées représentent une grande partie des données qui ne peuvent pas être aussi facilement compressées que le contenu xml.

Enfin, si ma mémoire est bonne, zip utilise quelque chose comme l'encodage par dictionnaire, qui est particulièrement efficace sur les fichiers ascii et encore plus sur le XML en raison de leur répétitivité.

La compression des données expliquée : http://mattmahoney.net/dc/dce.html

3voto

Aperture Points 850

Considérez ce XML :

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

Un XML a une structure très répétitive, Zip tire profit de ces répétitions pour construire un dictionnaire dont motif a plus d'occurrences et, lors de la compression, utilise moins de bits pour stocker plus de répétitions. motifs et plus de bits pour stocker moins de répétitions motif .

Quand vous concaténer ces fichiers, le fichier source (la source pour zip) est gros mais contient beaucoup plus des motifs répétés parce que la distribution des structures ennuyeuses d'un XML sont amorti dans le grand fichier entier, donnant la chance au ZIP de stocker ces motif en utilisant moins de bits.

Maintenant, si vous combinez différents XML dans un seul fichier, même si ces fichiers ont des noms de balises complètement différents, l'algorithme de compression trouvera la meilleure solution. motif répartition sur l'ensemble des fichiers et non fichier par fichier.

Au final, l'algorithme de compression a trouvé la meilleure distribution de motifs répétés.

-1voto

Loren Pechtel Points 2489

En plus de la réponse de 7-Zip, il existe une autre approche qui n'est pas aussi bonne mais qui vaut la peine d'être testée si, pour une raison quelconque, vous ne voulez pas utiliser 7-Zip :

Compresser le fichier zip. Normalement, un fichier zip est incompressible, mais lorsqu'il contient un grand nombre de fichiers identiques, le compresseur peut trouver cette redondance et la compresser. Notez que j'ai également constaté un petit gain en traitant un grand nombre de fichiers sans redondance. Si vous vous souciez vraiment de la taille, cela vaut la peine d'essayer si vous avez un grand nombre de fichiers dans votre zip.

0 votes

Cela ne fonctionne que si vous faites le premier zip avec la compression désactivée comme je l'ai mentionné ci-dessus.

0 votes

@MontyHarder Je l'ai vu fonctionner avec la compression activée.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X