下载并解压缩内存中的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文件?的主要内容,如果未能解决你的问题,请参考以下文章