web-dev-qa-db-fra.com

Télécharger et décompresser le fichier gzippé en mémoire?

Je voudrais télécharger un fichier en utilisant urllib et décompresser le fichier en mémoire avant de l'enregistrer.

Voici ce que j'ai en ce moment:

response = urllib2.urlopen(baseURL + filename)
compressedFile = StringIO.StringIO()
compressedFile.write(response.read())
decompressedFile = gzip.GzipFile(fileobj=compressedFile, mode='rb')
outfile = open(outFilePath, 'w')
outfile.write(decompressedFile.read())

Cela finit par écrire des fichiers vides. Comment puis-je réaliser ce que je recherche?

Réponse mise à jour:

#! /usr/bin/env python2
import urllib2
import StringIO
import gzip

baseURL = "https://www.kernel.org/pub/linux/docs/man-pages/"        
# check filename: it may change over time, due to new updates
filename = "man-pages-5.00.tar.gz" 
outFilePath = filename[:-3]

response = urllib2.urlopen(baseURL + filename)
compressedFile = StringIO.StringIO(response.read())
decompressedFile = gzip.GzipFile(fileobj=compressedFile)

with open(outFilePath, 'w') as outfile:
    outfile.write(decompressedFile.read())
36
OregonTrail

Vous devez rechercher le début de compressedFile après y avoir écrit mais avant de le passer à gzip.GzipFile(). Sinon, il sera lu de bout en bout par le module gzip et y apparaîtra comme un fichier vide. Voir ci-dessous:

#! /usr/bin/env python
import urllib2
import StringIO
import gzip

baseURL = "https://www.kernel.org/pub/linux/docs/man-pages/"
filename = "man-pages-3.34.tar.gz"
outFilePath = "man-pages-3.34.tar"

response = urllib2.urlopen(baseURL + filename)
compressedFile = StringIO.StringIO()
compressedFile.write(response.read())
#
# Set the file's current position to the beginning
# of the file so that gzip.GzipFile can read
# its contents from the top.
#
compressedFile.seek(0)

decompressedFile = gzip.GzipFile(fileobj=compressedFile, mode='rb')

with open(outFilePath, 'w') as outfile:
    outfile.write(decompressedFile.read())
46
crayzeewulf

Pour ceux qui utilisent Python 3, la réponse équivalente est:

import urllib.request
import io
import gzip

response = urllib.request.urlopen(FILE_URL)
compressed_file = io.BytesIO(response.read())
decompressed_file = gzip.GzipFile(fileobj=compressed_file)

with open(OUTFILE_PATH, 'wb') as outfile:
    outfile.write(decompressed_file.read())
14
lyschoening

Si vous avez Python 3.2 ou supérieur, la vie serait beaucoup plus facile:

#!/usr/bin/env python3
import gzip
import urllib.request

baseURL = "https://www.kernel.org/pub/linux/docs/man-pages/"
filename = "man-pages-4.03.tar.gz"
outFilePath = filename[:-3]

response = urllib.request.urlopen(baseURL + filename)
with open(outFilePath, 'wb') as outfile:
    outfile.write(gzip.decompress(response.read()))

Pour ceux qui s'intéressent à l'histoire, voir https://bugs.python.org/issue3488 et https://hg.python.org/cpython/rev/3fa0a9553402 .

11
Chih-Hsuan Yen