[使用gzip编码的大块文件下载大文件(Python 3.4)

问题描述 投票:3回答:1

如果我请求文件并指定gzip的编码,该如何处理?

通常,当我有大文件时,请执行以下操作:

while True:
   chunk = resp.read(CHUNK)
   if not chunk: break
   writer.write(chunk)
   writer.flush()

其中CHUNK是某种大小(以字节为单位,writer是一个open()对象,而resp是从urllib请求生成的请求响应。

因此,在大多数情况下,响应头包含'gzip'作为返回的编码,这很简单,我会执行以下操作:

decomp = zlib.decompressobj(16+zlib.MAX_WBITS)
data = decomp.decompress(resp.read())
writer.write(data)
writer.flush()

或此:

f = gzip.GzipFile(fileobj=buf)
writer.write(f.read())

其中buf是BytesIO()。

但是,如果我尝试解压缩gzip响应,则会出现问题:

while True:
   chunk = resp.read(CHUNK)
   if not chunk: break
   decomp = zlib.decompressobj(16+zlib.MAX_WBITS)
   data = decomp.decompress(chunk)
   writer.write(data)
   writer.flush()

有没有一种方法可以解压缩gzip数据,使其分解成小块?还是我需要将整个文件写入磁盘,解压缩然后将其移至最终文件名?使用32位Python,我遇到的部分问题是我可以摆脱内存错误。

谢谢

python python-3.x urllib2 urllib chunked-encoding
1个回答
2
投票

我想我找到了我希望分享的解决方案。

def _chunk(response, size=4096):
     """ downloads a web response in pieces """
    method = response.headers.get("content-encoding")
    if method == "gzip":
        d = zlib.decompressobj(16+zlib.MAX_WBITS)
        b = response.read(size)
        while b:
            data = d.decompress(b)
            yield data
            b = response.read(size)
            del data
    else:
        while True:
            chunk = response.read(size)
            if not chunk: break
            yield chunk

[如果有人有更好的解决方案,请添加。基本上,我的错误是zlib.decompressobj()的创建。我在错误的位置创建它。

这似乎也适用于python 2和3,所以有一个加号。

© www.soinside.com 2019 - 2024. All rights reserved.