web-dev-qa-db-fra.com

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

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

Méthode 1: ne les compressez pas

Résultats:

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

Méthode 2: Zip chaque fichier et lui envoyer 10 000 fichiers xml

Commander:

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 fichier Zip unique contenant 10 000 fichiers XML

Commander:

Zip all.Zip $(ls -1)

Résultats:

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

Méthode 4: Concaténez les fichiers en un seul fichier et compressez-le

Commander:

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

Résultats:

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

Des questions:

  • Pourquoi ai-je des résultats tellement meilleurs alors que je ne fais que compresser un fichier?
  • Je m'attendais à obtenir des résultats nettement meilleurs 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'essayais d'utiliser gzip, obtiendrais-je des résultats différents?

Information additionnelle:

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

Edit: métadonnées

Une réponse suggère que la différence réside dans les métadonnées du système stockées dans le fichier 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 reste environ 10 Mo d’espace inexpliqué.

124
sixtyfootersdude

Zip traite le contenu de chaque fichier séparément lors de la compression. Chaque fichier aura son propre flux compressé. L'algorithme de compression (généralement DEFLATE ) permet d'identifier les sections répétées. Cependant, Zip ne prend pas en charge la recherche de redondance entre les fichiers.

C'est pourquoi il y a tellement d'espace supplémentaire lorsque le contenu se trouve dans plusieurs fichiers: cela place le même flux compressé dans le fichier plusieurs fois.

128
Alan Shutko

La compression Zip est basée sur des motifs répétitifs dans les données à compresser. Plus la taille du fichier est longue, plus la compression est longue, plus les motifs peuvent être trouvés et utilisés plus longtemps.

Simplifié, si vous compressez un fichier, le dictionnaire qui associe des codes (courts) à des modèles (plus longs) est nécessairement contenu dans chaque fichier Zip résultant. Si vous zippez un fichier long, le dictionnaire est "réutilisé" et gagne en efficacité, même sur tous les contenus.

Si vos fichiers sont même un peu similaires (le texte l'est toujours), la réutilisation du 'dictionnaire' devient très efficace et le résultat est un fichier Zip total beaucoup plus petit.

48
Aganju

Dans Zip, chaque fichier est compressé séparément. Le contraire est «compression solide», c'est-à-dire que les fichiers sont compressés ensemble. 7-Zip et Rar utilisent la compression solide par défaut. Gzip et Bzip2 ne peuvent pas compresser plusieurs fichiers, donc Tar est utilisé en premier, ayant le même effet qu'une compression solide.

Comme le fichier XML a une structure similaire et probablement un contenu similaire, si les fichiers sont compressés ensemble, la compression sera plus élevée.

Par exemple, si un fichier contient la chaîne "<content><element name=" et que le compresseur a déjà trouvé cette chaîne dans un autre fichier, il sera remplacé par un petit pointeur sur la correspondance précédente. Si le compresseur n'utilise pas de compression solide, la première occurrence de la chaîne dans le fichier sera enregistré sous la forme d'un littéral plus volumineux.

43
ggf31416

Zip ne stocke pas uniquement le contenu du fichier, il stocke également des métadonnées de fichier telles que l'ID utilisateur propriétaire, les autorisations, les temps de création et de modification, etc. Si vous avez un fichier, vous avez un ensemble de métadonnées; si vous avez 10 000 fichiers, vous avez 10 000 jeux de métadonnées.

9
Mike Scott

Une option manquée par l'OP consiste à compresser tous les fichiers avec la compression désactivée, puis à compresser le fichier Zip résultant avec la compression réglée au maximum. Cela imite grossièrement le comportement des archives compressées * nix .tar.Z, .tar.gz, .tar.bz, etc., en permettant à la compression d’exploiter les redondances entre les limites de fichiers (ce que l’algorithme Zip ne peut pas exécuter lorsqu’il est exécuté dans un seul fichier passer). Cela permet d'extraire les fichiers XML individuels ultérieurement, mais maximise la compression. L'inconvénient est que le processus d'extraction nécessite une étape supplémentaire, utilisant temporairement beaucoup plus d'espace disque que ce qui serait nécessaire pour un fichier .Zip normal.

Avec l'omniprésence d'outils gratuits comme 7-Zip pour étendre la famille tar à Windows, il n'y a vraiment aucune raison de ne pas utiliser .tar.gz ou .tar.bz, etc., car Linux, OS X et les BSD ont tous outils natifs pour les manipuler.

7
Monty Harder

Le format de compression Zip stocke et compresse chaque fichier séparément. Il ne tire pas parti de la répétition entre fichiers, mais uniquement au sein d’un fichier.

La concaténation du fichier permet à Zip de tirer parti des répétitions de tous les fichiers, ce qui entraîne une compression considérablement plus importante.

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

5
BonsaiOak

Mike Scott a mentionné, à côté des métadonnées, que l’algorithme de compression est surchargé.

Lors de la compression de plusieurs petits fichiers, vous devez être très chanceux pour pouvoir les compresser en remplissant un bloc de compression. Lors de la compression d’un seul bloc monolithique, le système peut continuer à transmettre des données à son algorithme en ignorant les "limites" (faute de meilleur mot) des fichiers individuels.

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

Enfin, si la mémoire est bonne, Zip utilise quelque chose comme le codage par dictionnaire, ce qui est particulièrement efficace sur les fichiers ASCII et plus encore sur XML en raison de leur répétitivité.

Explication de la compression des données: http://mattmahoney.net/dc/dce.html

4
GapWim

Considérons ce XML:

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

Un XML a une structure très répétitive, Zip profite de ces répétitions pour construire un dictionnaire dont pattern a plus d’occurrences puis, lors de la compression, utilise moins de bits pour stocker davantage de répétitions patterns et plus de bits pour stocker moins répété pattern .

Lorsque vous concatérez ces fichiers, le fichier source (la source de Zip) est volumineux mais contient beaucoup plus de motifs répétés car la distribution des structures ennuyeuses d’un XML est amortie dans le gros fichier entier, donnant la possibilité à Zip de stocker ces pattern en utilisant moins de bits.

Maintenant, si vous combinez différents fichiers XML dans un seul fichier, même lorsque ces fichiers portent des noms de balises complètement différents, l'algorithme de compression trouvera la meilleure distribution pattern parmi tous les fichiers et non fichier par fichier.

En fin de compte, l'algorithme de compression a trouvé la meilleure distribution de motifs répétés.

3
rnrneverdies