下载并解压缩内存中的gzip文件?

Posted

技术标签:

【中文标题】下载并解压缩内存中的gzip文件?【英文标题】:Download and decompress gzipped file in memory? 【发布时间】:2013-02-27 11:03:35 【问题描述】:

我想使用 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/"        
# 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())

【问题讨论】:

解压到磁盘有什么问题? 我正在解压缩到磁盘,只是永远不要让压缩的字节接触磁盘。 compressedFile 有没有得到过再见? 是的,在更新版本中 不相关:您可以使用shutil.copyfileobj(decompressed_file, outfile) 逐块保存文件,而无需将其加载到内存中。 【参考方案1】:

您需要在写入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())

【讨论】:

原来我可以利用 StringIO 的__init__,查看更新后的问题。 是的。那效果更好。 :) 我不会编辑我的答案,因为您已经添加了更新的答案。谢谢。 @OregonTrail: 或者你可以去掉中间人和pass response directly。顺便说一句,不要将答案放入问题中; you are encouraged to post your own answer.【参考方案2】:

对于那些使用 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())

【讨论】:

它不起作用:您正在尝试将字节写入文本文件;改用二进制模式。试试看:copyfileobj(GzipFile(fileobj=response), open(outfile_path, 'wb'))【参考方案3】:

如果你有 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。

【讨论】:

迄今为止最好的解决方案。【参考方案4】:

一行代码打印解压后的文件内容:

print gzip.GzipFile(fileobj=StringIO.StringIO(urllib2.urlopen(DOWNLOAD_LINK).read()), mode='rb').read()

【讨论】:

以上是关于下载并解压缩内存中的gzip文件?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 下载并解压缩文件

iPhone:在运行时在主包子目录中下载 zip 并解压缩

Linux打包解包压缩解压缩

Linux打包解包压缩解压缩

Linux打包解包压缩解压缩

linux打包,压缩,解压的几种方式用法