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

130voto

Alan Shutko Points 4028

Zip traite le contenu de chaque fichier séparément lors de la compression. Chaque fichier aura son propre flux compressé. Il existe un support au sein de l'algorithme de compression (généralement DEFLATE ) pour identifier les sections répétées. Cependant, Zip ne permet pas de trouver les redondances entre les fichiers.

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

9 votes

C'est également la raison pour laquelle certains outils de compression vous offrent la possibilité de compresser les fichiers séparément ou comme une seule entité. (Bien qu'en général, cela signifie également que vous devez décompresser une plus grande partie de l'archive que vous ne le feriez autrement si vous voulez visualiser un seul fichier).

28 votes

@JAB : Les outils de compression comme 7z et rar utilisent le terme d'archive "solide" pour regrouper plusieurs fichiers tête-bêche dans des flux de compression plus importants. Avec une taille modérée comme 64Mo, l'accès aléatoire à un seul fichier peut nécessiter de décompresser jusqu'à 64Mo de données depuis le début du bloc de compression dans lequel il se trouve. Vous pouvez obtenir un bon compromis entre l'accès aléatoire et la recherche de redondance entre les fichiers. 7z peut utiliser le schéma de compression LZMA, plus efficace (mais plus lent à compresser), ce qui constitue un autre avantage par rapport à zip.

0 votes

Est-ce que vous dites que there is no support in Zip to find redundancy between files est dans la spécification du fichier zip ?

48voto

Aganju Points 9650

La compression ZIP est basée sur des motifs répétitifs dans les données à compresser, et la compression s'améliore au fur et à mesure que le fichier est plus long, car des motifs plus nombreux et plus longs peuvent être trouvés et utilisés.

En simplifiant, si vous comprimez un fichier, le dictionnaire qui associe des codes (courts) à des modèles (plus longs) est nécessairement contenu dans chaque fichier compressé résultant ; si vous comprimez un fichier long, le dictionnaire est "réutilisé" et devient encore plus efficace pour l'ensemble du contenu.

Si vos fichiers sont un tant soit peu similaires (comme c'est toujours le cas pour le texte), la réutilisation du "dictionnaire" devient très efficace, et le résultat est un zip total beaucoup plus petit.

3 votes

Le ZIP fait à la fois de l'archivage et de la compression. Cela signifie-t-il que le ZIP compresse chaque fichier individuellement, même s'ils se retrouvent tous dans le même fichier ZIP ?

2 votes

C'est un peu obligé - imaginez que vous supprimez un seul fichier, vous ne voudriez pas qu'il passe une autre demi-heure à recompresser le reste avec un nouveau "dictionnaire". - De plus, il suppose probablement que des fichiers différents ont besoin de "dictionnaires" très différents.

2 votes

Je ne vois pas pourquoi il le faudrait. Avec les outils Unix, j'archiverais d'abord un fichier avec tar, puis je le compresserais avec gzip/bz2/lzma. L'algorithme de compression ne se soucie pas du nombre de fichiers encodés dans l'archive. Par ailleurs, est-il vraiment courant de supprimer un seul fichier d'une archive compressée ? Je ne pense pas l'avoir déjà fait.

45voto

ggf31416 Points 531

Dans Zip, chaque fichier est compressé séparément. Le contraire est la "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. Tar est donc utilisé en premier, ce qui a le même effet que la compression solide.

Comme les fichiers xml ont 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 de caractères "<content><element name=" si le compresseur a déjà trouvé cette chaîne dans un autre fichier, il la remplacera par un petit pointeur vers la correspondance précédente, si le compresseur n'utilise pas la 'compression solide', la première occurrence de la chaîne dans le fichier sera enregistrée comme un littéral plus grand.

9voto

Tyler Griffiths Points 11

Zip ne se contente pas de stocker le contenu du fichier, il stocke également les métadonnées du fichier, comme l'identifiant de l'utilisateur propriétaire, les autorisations, les heures de création et de modification, etc. Si vous avez un fichier, vous avez un jeu de métadonnées ; si vous avez 10 000 fichiers, vous avez 10 000 jeux de métadonnées.

3 votes

Bon point, mais les métadonnées du système ne prennent que 1,4 Mo d'espace. Voir mon édition.

1 votes

Je ne suis pas familier avec l'algorithme zip, mais les métadonnées ne sont pas seulement des informations sur le fichier, mais aussi des choses comme la taille et un dictionnaire, éventuellement des informations sur la distribution des caractères. Un dictionnaire sur un fichier texte non vide sera non nul. C'est probablement la raison pour laquelle les métadonnées sont plus grandes dans vos fichiers xml que dans vos fichiers vides.

0 votes

C'était ma première pensée. Informations sur l'en-tête du fichier zip

8voto

murrekatt Points 2712

Une option oubliée par l'OP est de compresser tous les fichiers ensemble avec la compression désactivée, puis de compresser le zip résultant avec la compression maximale. Cela émule 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 fichiers (ce que l'algorithme ZIP ne peut pas faire lorsqu'il est exécuté en une seule passe). Les fichiers XML individuels peuvent ainsi être extraits ultérieurement, mais la compression est maximisée. L'inconvénient est que le processus d'extraction nécessite une étape supplémentaire, utilisant temporairement beaucoup plus d'espace disque que pour un .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 un .tar.gz ou .tar.bz, etc., puisque Linux, OS X et les BSD disposent tous d'outils natifs pour les manipuler.

0 votes

Gzip et bzip2 risquent d'être encore pires, car ils sont conçus pour compresser des flux, et devront donc commencer à produire des données compressées avant même de connaître toutes les données à compresser.

0 votes

@rackandboneman : C'est le compromis que vous devez faire lorsque vous compressez des fichiers plus grands que la quantité de mémoire que vous êtes prêt à utiliser au moment de la compression. (Et aussi, la quantité de temps CPU nécessaire pour trouver quelque chose de globalement optimal serait énorme). Un dictionnaire de compression volumineux peut également augmenter la mémoire requise pour les opérations suivantes décompression . Il s'agit d'une option pour LZMA ( xz / 7-zip). Quoi qu'il en soit, les dictionnaires adaptatifs peuvent repérer les modèles une fois qu'ils sont visibles. Ce n'est pas comme s'ils construisaient un système de codage statique basé sur les 32 premiers caractères. C'est pourquoi gzip ne craint pas.

0 votes

J'aime beaucoup cette "astuce" si vous devez rester au format zip. Je ne suis pas d'accord avec votre "aucune raison de ne pas utiliser 7-zip" - si j'envoie un fichier à un ami non technique, je veux être sûr qu'il pourra l'ouvrir facilement. Si j'envoie un fichier à un client d'affaires, c'est encore mieux.

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