8
votes

Décompresser une partie d'un fichier .gz à l'aide de Python

Alors voici le problème. J'ai un fichier exemple.gz qui est d'environ 60 ko de taille. Je veux décompresser les premiers 2000 octets de ce fichier. Je rencontre une erreur de contrôle CRC échec, je suppose que parce que le champ GZIP CRC apparaît à la fin du fichier, et il nécessite l'intégralité du fichier gzippé de décompresser. Y a-t-il un moyen de contourner ceci? Je me fiche de la vérification du CRC. Même si je ne parviens pas à décompresser à cause de mauvais CRC, c'est bon. Existe-t-il un moyen de contourner cela et de décompresser des fichiers partiels partiels?

Le code que j'ai jusqu'à présent est p> xxx pré>

l'erreur rencontrée est p>

File "gunzip.py", line 27, in ?
    data = f.read()
File "/usr/local/lib/python2.4/gzip.py", line 218, in read
  self._read(readsize)
File "/usr/local/lib/python2.4/gzip.py", line 273, in _read
  self._read_eof()
File "/usr/local/lib/python2.4/gzip.py", line 309, in _read_eof
  raise IOError, "CRC check failed"
IOError: CRC check failed


1 commentaires

Parce que je suis intéressé par le premier peut-être 4K des données compressées.


4 Réponses :


12
votes

Je semble que vous devez regarder dans python zlib à la place

Le format GZIP repose sur zlib, mais introduit un concept de compression au niveau de fichier avec la vérification de la CRC, ce qui semble être ce que vous ne voulez pas / besoin pour le moment.

Voir par exemple ces Code Snippets de Dough Hellman < / a>

EDIT : le code sur le site de Doubh Hellman ne montre comment compresser ou décompresser avec zlib. Comme indiqué ci-dessus, Gzip est "Zlib avec une enveloppe" et vous devrez décoder l'enveloppe avant d'accéder aux données compressées de ZLIB en soi . Voici plus d'informations pour y aller, ce n'est vraiment pas si compliqué:

  • See RFC 1952 pour plus de détails sur le format gzip
  • Ce format commence par un en-tête de 10 octets, suivi d'éléments facultatifs non compressés tels que le nom de fichier ou un commentaire, suivi des données compressées de ZLIB, suivie de la CRC-32 (précisément un "Adler32" CRC ).
  • En utilisant Module de structure de Python , analysant le L'en-tête doit être relativement simple
  • la séquence ZLIB (ou ses premiers mille octets, car c'est ce que vous voulez faire) peut alors être décompressé avec le module ZLIB de Python, comme indiqué dans les exemples ci-dessus
  • Problèmes possibles à gérer: S'il y a plus d'un fichier dans l'archive GZIP, et si le deuxième fichier commence dans un bloc de quelques milliers d'octets, nous souhaitons décompresser.

    Désolé de ne fournir aucune procédure simple ni un extrait de prêt-à-faire, cependant décoder le fichier avec l'indication ci-dessus doit être relativement rapide et simple.


2 commentaires

@MJV ... Quel appartement de code particulier s'applique à l'exemple ci-dessus. J'ai traversé le lien et j'ai lu avec le travail avec des flux. Nulle part ça ne dit-il que son travail avec des flux GZIP. Je suppose que cela fonctionne avec des flux ZLIB (a testé avec des flux de zlib)


@known: vérifier mon édition; Les extraits de code concernent la compression / décompression à / de zlib pur. Le format GZIP implique le Fist analyser un petit en-tête non compressé, avant de trouver sa "charge utile" zlip qui peut être décompressée comme indiqué.



10
votes

Je ne vois aucune raison possible pour laquelle vous voudriez décompresser les 2000 premiers octets compressés. Selon les données, cela peut se décompresser à un nombre quelconque d'octets de sortie.

Vous voulez sûrement décompresser le fichier et arrêtez-vous lorsque vous avez décompressé autant de fichier dont vous avez besoin, quelque chose comme: p>

f = gzip.GzipFile(fileobj=open('postcode-code.tar.gz', 'rb'))
data = f.read(4000)
print data


6 commentaires

F.Read (2000) Voici la lecture des premiers 2000 octets de données décompressées. Je suis intéressé par les 2000 premiers octets de données compressées.


Pourquoi? Qu'est-ce que votre application est votre application?


:-) J'essaie de trouver une chaîne "xyz" dans les 4 000 premières données. En supposant que je décompresse 2K de données gzippées et de terre avec 4K de données décompressées, je peux rechercher / grep dans ce 4K pour la chaîne. Tout le code de recherche est déjà en place ..


Supposons que tout ce que je vais obtenir, c'est le premier 2k de données compressées à partir d'un fichier 60K .gz. Après cela rien. Nada. J'ai besoin trouver ma corde dans la partie décompressée de ce 2k


Si vous souhaitez rechercher le premier 4k de données non compressées, recherchez la première 4K des données non compressées, comme je le fais dans ma réponse (peut-être changer de 4000 à 4096). N'essayez pas de deviner que 2K va décompresser jusqu'à 4k. Ce n'est peut-être pas. Il ne s'agit que de décompresser seulement 2k, ou cela pourrait décompresser à quelques mégaoctets.


C'est parfait. Merci beaucoup! Pas besoin de hacks sales.



2
votes

Je rencontre également ce problème lorsque j'utilise mon script Python pour lire des fichiers compressés générés par Gzip Tool sous Linux et les fichiers d'origine ont été perdus.

En lisant la mise en œuvre de gzip.py de python , J'ai trouvé que gzip.gzipfile avait des méthodes similaires de classe de fichiers et a exploité le module Zip Python pour traiter les données de / compression. Dans le même temps, la méthode _Read_eof () est également présente pour vérifier le CRC de chaque fichier.

mais dans certaines situations, comme le traitement du flux de traitement ou .gz sans corriger le CRC (mon problème), un ioerror ("CRC Check a échoué") sera soulevé par _Read_eof (). Par conséquent, j'essaie de modifier le module GZIP pour désactiver la vérification de la CRC et enfin que ce problème a disparu. xxx

https://github.com/caesar0301/pcapex/blob/master/live-scripts/gzip_mod.py

Je sais que c'est une solution de force brute, mais elle économise beaucoup de temps pour vous réécrire des méthodes de faible niveau à l'aide du module ZIP, comme de la lecture de Data Chuck par Chuck depuis les fichiers zippés et d'extraire la ligne de données par ligne, la plupart dont a été présent dans le module GZIP.

Jamin


0 commentaires

14
votes

Le problème avec le module GZIP n'est pas limitant au décompression du fichier partiel, l'erreur ne se produit que à la fin lorsqu'il essaie de vérifier la somme de contrôle du contenu décompressé. (La somme de contrôle d'origine est stockée à la fin du fichier compressé afin que la vérification ne fonctionne jamais jamais avec un fichier partiel.)

La clé est de tromper GZIP dans la vérification. Le Réponse de Caesar0301 Cela en modifiant le code source GZIP, mais il n'est pas nécessaire d'aller aussi loin, de simples corriger le singe faire. J'ai écrit ce gestionnaire de contexte pour remplacer temporairement gzip.gzipfile._read_eof pendant que je décompresse le fichier partiel: xxx

un exemple d'utilisation: xxx


0 commentaires