Загружать и распаковывать gzip-файл в память?

Я хотел бы загрузить файл с помощью urllib и распаковать файл в памяти перед сохранением.

Это то, что я имею прямо сейчас:

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()) 

Это заканчивается написанием пустых файлов. Как я могу добиться того, что мне нужно?

Обновленный ответ:

 #! /usr/bin/env python2 import urllib2 import StringIO import gzip baseURL = "https://www.kernel.org/pub/linux/docs/man-pages/" filename = "man-pages-3.34.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()) 

4 Solutions collect form web for “Загружать и распаковывать gzip-файл в память?”

Вам нужно искать начало compressedFile после его записи, но перед передачей его в gzip.GzipFile() . В противном случае он будет считываться с конца модулем gzip и будет отображаться в виде пустого файла. Смотри ниже:

 #! /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()) 

Для тех, кто использует Python 3, эквивалентный ответ:

 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()) 

Если у вас есть Python 3.2 или выше, жизнь будет намного проще:

 #!/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())) 

Для тех, кто интересуется историей, см. https://bugs.python.org/issue3488 и https://hg.python.org/cpython/rev/3fa0a9553402 .

Один код строки для печати содержимого распакованного файла:

 print gzip.GzipFile(fileobj=StringIO.StringIO(urllib2.urlopen(DOWNLOAD_LINK).read()), mode='rb').read() 
Python - лучший язык программирования в мире.