【问题标题】:downloading a large file in chunks with gzip encoding (Python 3.4)使用 gzip 编码(Python 3.4)分块下载大文件
【发布时间】:2016-01-06 11:54:36
【问题描述】:

如果我请求文件并指定 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】:

    我想我找到了一个我想分享的解决方案。

    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 中都有效,所以有一个优点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-09
      • 1970-01-01
      • 2011-07-13
      • 2012-04-17
      • 1970-01-01
      相关资源
      最近更新 更多