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


Supposons que je possède 10 000 fichiers XML. Maintenant, supposons que je veuille les envoyer à un ami. Avant de les envoyer, je voudrais les compresser.

Méthode 1: ne pas les compresser

Résultats:

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

Méthode 2: compresser 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 seul fichier zip 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éner les fichiers en un seul fichier et le compresser

Commander:

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

Résultats:

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

Des questions:

  • Pourquoi obtiens-je des résultats tellement meilleurs quand je ne fais que compresser un seul fichier?
  • Je m'attendais à obtenir des résultats considérablement 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'ai essayé d'utiliser gzip aurais-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)

Modifier: 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 y a encore ~ ​​10 Mo d'espace inexpliqué.


119
2017-12-14 17:30


origine


Si je ne me trompe pas, c'est ce phénomène qui amène les gens à faire .tar.gz au lieu de simplement compresser tout le répertoire. - corsiKa
UNE question similaire a déjà été demandé, tl; dr utiliser des archives 7zip solides. - Dmitry Grigoryev
@sixtyfootersdude Pour tester certaines des réponses, pouvez-vous essayer de compresser le fichier zip produit dans la méthode 3? Je soupçonne que cela réduira la taille du fichier à quelque chose de comparable à la méthode 4. - Travis
Au lieu de $(ls -1), utilisez juste *: for x in *; zip all.zip * - muru
Si vous voulez faire une compression solide avec ZIP, voici une solution: créez d'abord un non compressé ZIP contenant tous vos fichiers. Ensuite, placez ce ZIP dans un autre ZIP compressé. - user20574


Réponses:


Zip traite le contenu de chaque fichier séparément lors de la compression. Chaque fichier aura son propre flux compressé. Il y a un support dans l'algorithme de compression (généralement DÉGONFLER) pour 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 est dans plusieurs fichiers: cela place le même flux compressé dans le fichier plusieurs fois.


124
2017-12-14 19:24



C'est également pour cette raison que certains outils de compression vous permettent de compresser les fichiers séparément ou en une seule entité. (Bien que cela signifie généralement que vous devez décompresser plus de l'archive que vous ne le voudriez autrement si vous ne voulez voir qu'un seul fichier.) - JAB
@JAB: Les outils de compression tels que 7z et rar utilisent le terme d'archive "solide" pour placer plusieurs fichiers en tête-à-tête dans des flux de compression plus importants. Avec une taille de bloc modérée telle que 64 Mo, un accès aléatoire à un seul fichier peut nécessiter une décompression de 64 Mo de données dès le début du bloc de compression dans lequel il se trouve. 7z peut utiliser le schéma de compression LZMA le plus efficace (mais plus lent à compresser), ce qui constitue un autre avantage par rapport au zip. - Peter Cordes
Voulez-vous dire que there is no support in Zip to find redundancy between files est dans la spécification du fichier zip? - sixtyfootersdude
@sixtyfootersdude De nombreux algorithmes de compression, tels que DEFLATE, fonctionnent comme un flux. Pour récupérer suffisamment d'informations pour décompresser une partie du flux, vous devez traiter l'intégralité du flux jusqu'à ce point. S'ils essayaient de trouver une redondance entre les fichiers, vous devrez décompresser tous les 1000 fichiers pour arriver au dernier. C'est généralement ainsi que fonctionne tgz. Toutefois, zip a été conçu pour vous permettre d'extraire des fichiers individuels. tgz est conçu pour être plus tout-ou-rien - Cort Ammon
@sixtyfootersdude - c'est correct. Pour paraphraser Cort: Les spécifications pkzip ne prennent pas en charge les fichiers croisés. Si c'est le cas, l'extraction d'un fichier peut nécessiter l'extraction de l'archive complète (et de chaque fichier). - James Snell


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

Simplifié, si vous compressez un fichier, le dictionnaire qui associe les codes (courts) aux modèles (plus longs) est nécessairement contenu dans chaque fichier zip résultant; Si vous compressez un fichier long, le dictionnaire est «réutilisé» et devient encore plus efficace sur tout le contenu.

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


46
2017-12-14 18:48



ZIP effectue à la fois l'archivage et la compression. Est-ce que cela signifie que ZIP compresse chaque fichier individuellement, même s'ils se retrouvent tous dans le même fichier ZIP? - gerrit
il faut en quelque sorte - imaginez que vous supprimiez un seul fichier, vous ne voudriez pas qu’il passe une demi-heure à recompresser le reste avec un nouveau «dictionnaire». - en outre, cela suppose probablement que différents fichiers nécessitent des «dictionnaires» très différents. - Aganju
Je ne vois pas pourquoi. Avec les outils Unix, je commencerais par archiver un fichier avec tar, puis le compresser avec gzip / bz2 / lzma. L'algorithme de compression ne se soucie pas du nombre de fichiers encodés dans l'archive. En outre, est-il courant de supprimer un seul fichier d’une archive compressée? Je ne pense pas avoir déjà fait ça. - gerrit
Je ne suis pas en désaccord, et c'est probablement une bonne façon. Je n'ai pas conçu ou écrit ZIP. Je viens de dire ce que ça fait ... - Aganju
@gerrit Il a ses propres problèmes. Zip est conçu pour vous permettre d'accéder rapidement à n'importe quel fichier de l'archive - essayez de décompresser un fichier unique à partir d'une archive UHA de 100 Go et vous verrez pourquoi ils ont choisi cette méthode. Il est également conçu pour être ajouté - vous pouvez avoir votre fichier zip de sauvegarde et continuer à ajouter (ou remplacer) des fichiers selon vos besoins. Tout cela est une aide énorme lors de l'utilisation des archives. Le compromis est que si vous compressez des fichiers qui sont très similaires (ce qui est ne pas tout cela commun), il ne peut pas exploiter les similitudes pour réduire la taille des archives. - Luaan


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, avec le même effet que la 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 le compresseur a déjà trouvé cette chaîne dans un autre fichier, il le 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 est plus grande


42
2017-12-14 20:02





Zip ne se contente pas de stocker le contenu du fichier, il enregistre également les métadonnées du fichier, telles que l'ID utilisateur, 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
2017-12-14 17:38



Bon point, mais les métadonnées du système ne prennent que 1,4 Mo d'espace. Voir mon montage - sixtyfootersdude
Je ne suis pas familier avec l'algorithme zip, mais les métadonnées ne sont pas uniquement des informations sur les fichiers, mais aussi des éléments tels que 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 vos fichiers vides. - Ben Richards
C'était ma première pensée. Informations d'en-tête de fichier zip - WernerCD
Cela explique seulement la différence entre 2 et 3 - pas 4. - Luaan
@Luaan Non, à la fois en 2 et 3, les métadonnées de tous les 10 000 fichiers sont incluses dans le ou les fichiers zip, de sorte que la taille totale du fichier est presque identique. Dans 4, il n'y a que des métadonnées pour un fichier et le fichier zip est beaucoup plus petit. - 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 au maximum. Cela simule grossièrement le comportement des archives compressées * nix .tar.Z, .tar.gz, .tar.bz, etc., en permettant à la compression d’exploiter les redondances à travers les limites de fichiers (que l’algorithme ZIP ne peut 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 l'étape supplémentaire, en 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 tels que 7-Zip pour étendre la famille tar à Windows, il n’ya vraiment aucune raison de ne pas utiliser de .tar.gz ou .tar.bz, comme Linux, OS X et les BSD ont tous des outils natifs pour les manipuler.


6
2017-12-15 15:50



gzip et bzip2 pourraient finir par empirer car ils sont conçus pour la compression des flux, ils devront donc commencer à générer des données compressées avant que toutes les données à compresser soient connues. - rackandboneman
@rackandboneman: C'est le compromis à faire lors de la compression de fichiers plus volumineux que la quantité de mémoire que vous souhaitez utiliser au moment de la compression. (En outre, la quantité de temps processeur requise pour trouver quelque chose d’optimalement au niveau mondial serait énorme.) Un dictionnaire de compression volumineux peut également augmenter la mémoire requise pour décompression. Ceci est une option pour LZMA (xz / 7-zip). Quoi qu’il en soit, les dictionnaires adaptatifs peuvent détecter les modèles une fois qu’ils sont visibles. Ce n'est pas comme si elle construisait juste un système de codage statique basé sur les premiers 32k. C'est pourquoi gzip ne craint pas. - Peter Cordes


Le format de compression zip stocke et compresse chaque fichier séparément. Il ne profite pas de la répétition entre les fichiers, mais uniquement dans un fichier.

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

Par exemple, disons que chaque fichier XML a un en-tête spécifique. Cet en-tête n'apparaît qu'une seule fois dans chaque fichier mais est répété 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 pouvait le faire.


5
2017-12-15 01:19



En quoi est-ce différent de l'une des 3 premières réponses déjà affichées 5 heures plus tôt? - Xen2050
@ Xen2050 Pas beaucoup de différence, j'ai juste pensé que je pourrais l'expliquer plus clairement. - BonsaiOak
@BonsaiOak - puis ajoutez un commentaire à la bonne réponse ou modifiez-le si vous avez assez de rep. Si ce n'est pas le cas, mais que votre commentaire apporte plus de clarté, quelqu'un d'autre pourrait choisir et modifier le message de toute façon. - AdamV
@AdamV je vois votre point. Ma réponse n'ajoute actuellement aucune information utile, même si elle a sans doute été faite lorsque je l'ai écrite. Il y a déjà des commentaires appropriés sous la première réponse, alors je ne vois pas non plus l'intérêt de les ajouter. Voulez-vous dire que je devrais juste fermer ma réponse? Quel mal y a-t-il à le laisser ouvert? - BonsaiOak


À côté des métadonnées, Mike Scott mentionne que l’algorithme de compression présente également des coûts supplémentaires.

Lorsque vous compressez un groupe de petits fichiers individuels, vous devez être très chanceux de pouvoir les compresser pour qu’il ne remplisse qu’un 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 mot) des fichiers individuels.

De plus, ASCII est connu pour avoir un facteur de compression élevé. plus xml est souvent très répétitif, ce qui fait que les métadonnées sont 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 correcte, zip utilise quelque chose comme l'encodage du dictionnaire, qui est particulièrement efficace sur les fichiers ASCII et encore plus sur les fichiers XML en raison de leur répétitivité.

Compression de données expliquée: http://mattmahoney.net/dc/dce.html


4
2017-12-14 18:02





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 profite de ces répétitions pour construire un dictionnaire dont modèle 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 à stocker moins répété modèle.

Lorsque vous enchaîner ces fichiers, le fichier source (la source du fichier zip) est volumineux mais contient beaucoup plus motifs répétés car la distribution des structures ennuyeuses d’un XML est amorti dans le grand fichier entier, donnant la possibilité de ZIP pour stocker ceux-ci modèle en utilisant moins de bits.

Maintenant, si vous combinez différents XML en un seul fichier, même lorsque ces noms de fichiers sont complètement différents, l’algorithme de compression trouvera le meilleur modèledistribution dans tous les fichiers et non fichier par fichier.

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


3
2017-12-16 01:27