web-dev-qa-db-fra.com

Utilisation du module GZIP avec Python

J'essaie d'utiliser le module Python GZIP pour décompresser simplement plusieurs fichiers .gz dans un répertoire. Notez que je ne veux pas lire les fichiers, mais seulement les décompresser. Après avoir cherché sur ce site pendant un moment, j'ai ce segment de code, mais cela ne fonctionne pas:

import gzip
import glob
import os
for file in glob.glob(PATH_TO_FILE + "/*.gz"):
    #print file
    if os.path.isdir(file) == False:
        shutil.copy(file, FILE_DIR)
        # uncompress the file
        inF = gzip.open(file, 'rb')
        s = inF.read()
        inF.close()

les fichiers .gz se trouvent au bon emplacement et je peux imprimer le chemin complet + nom du fichier avec la commande print, mais le module GZIP n'est pas exécuté correctement. Qu'est-ce que je rate?

23
user3111358

Si vous n'obtenez aucune erreur, le module gzip probablement est est exécuté correctement.

Je ne veux pas lire les fichiers, seulement les décompresser

Le module gzip ne fonctionne pas comme un programme d'archivage de bureau comme 7-Zip - vous ne pouvez pas "décompresser" un fichier sans le "lire". Ce que vous entendez probablement par "décompresser" est décrit plus précisément - du point de vue de la programmation - comme "lit un flux depuis un fichier compressé et l'écrit dans un nouveau fichier".

inF = gzip.open(file, 'rb')
s = inF.read()
inF.close()

Ici, vous ne faites que lire le flux. Il vous suffit de l'écrire dans un nouveau fichier:

inF = gzip.open(file, 'rb')
outF = open(outfilename, 'wb')
outF.write( inF.read() )
inF.close()
outF.close()
40
goncalopp

Vous devez utiliser with pour ouvrir les fichiers et, bien sûr, stocker le résultat de la lecture du fichier compressé. Voir gzip documentation :

import gzip
import glob
import os
import os.path

for gzip_path in glob.glob("%s/*.gz" % PATH_TO_FILE):
    if not os.path.isdir(gzip_path):
        with gzip.open(gzip_path, 'rb') as in_file:
            s = in_file.read()

        # Now store the uncompressed data
        path_to_store = gzip_fname[:-3]  # remove the '.gz' from the filename

        # store uncompressed file data from 's' variable
        with open(path_to_store, 'w') as f:
            f.write(s)

En fonction de ce que vous voulez faire, vous voudrez peut-être consulter tarfile et son option 'r:gz' pour ouvrir des fichiers.

6
Martin Thoma

Vous décompressez le fichier en variable s et ne faites rien avec elle. Vous devriez arrêter de chercher dans stackoverflow et lire au moins le tutoriel python. Sérieusement.

Quoi qu'il en soit, il y a plusieurs problèmes avec votre code:

  1. vous devez stocker les données décompressées dans s dans un fichier.

  2. il n'est pas nécessaire de copier les fichiers *.gz actuels. Parce que dans votre code, vous décompressez le fichier gzip original et non la copie.

  3. vous utilisez file, qui est un mot réservé, en tant que variable. Ce n’est pas une erreur, c’est une très mauvaise pratique.

Cela devrait probablement faire ce que vous vouliez:

import gzip
import glob
import os
import os.path

for gzip_path in glob.glob(PATH_TO_FILE + "/*.gz"):
    if os.path.isdir(gzip_path) == False:
        inF = gzip.open(gzip_path, 'rb')
        # uncompress the gzip_path INTO THE 's' variable
        s = inF.read()
        inF.close()

        # get gzip filename (without directories)
        gzip_fname = os.path.basename(gzip_path)
        # get original filename (remove 3 characters from the end: ".gz")
        fname = gzip_fname[:-3]
        uncompressed_path = os.path.join(FILE_DIR, fname)

        # store uncompressed file data from 's' variable
        open(uncompressed_path, 'w').write(s)
5
Jan Spurny

J'ai pu résoudre ce problème en utilisant le module de sous-processus:

for file in glob.glob(PATH_TO_FILE + "/*.gz"):
    if os.path.isdir(file) == False:
        shutil.copy(file, FILE_DIR)
        # uncompress the file
        subprocess.call(["gunzip", FILE_DIR + "/" + os.path.basename(file)])

Puisque mon objectif était simplement de décompresser l'archive, le code ci-dessus accomplit cela. Les fichiers archivés sont situés dans un emplacement central. Ils sont copiés dans une zone de travail, non compressés et utilisés dans un scénario de test. le module GZIP était trop compliqué pour ce que j'essayais d'accomplir.

Merci pour l'aide de tous. C'est très apprécié!

4
user3111358

Je pense qu'il existe une solution beaucoup plus simple que les autres solutions présentées, car l'opérateur voulait uniquement extraire tous les fichiers d'un répertoire:

import glob
from setuptools import archive_util

for fn in glob.glob('*.gz'):
  archive_util.unpack_archive(fn, '.')
0
Dalupus