【问题标题】:How to stream a gzip built on the fly in Python?如何流式传输在 Python 中动态构建的 gzip?
【发布时间】:2016-10-23 00:34:53
【问题描述】:

我想使用 asyncio 在网络上传输一个大日志文件。我从数据库中检索数据,对其进行格式化,使用 python 的 zlib 对其进行压缩并通过网络进行流式传输。

这基本上是我使用的代码:

@asyncio.coroutine
def logs(requests):
    # ...

    yield from resp.prepare(request)

    # gzip magic number and compression format
    resp.write(b'\x1f\x8b\x08\x00\x00\x00\x00\x00')
    compressor = compressobj()
    for row in rows:
        ip, uid, date, url, answer, volume = row
        NCSA_ROW = '{} {} - [{}] "GET {} HTTP/1.0" {} {}\n'
        row = NCSA_ROW.format(ip, uid, date, url, answer, volume)
        row = row.encode('utf-8')
        data = compressor.compress(row)
        resp.write(data)
    resp.write(compressor.flush())
    return resp

我检索到的文件无法使用 gunzip 和 zcat 打开引发以下错误:

gzip: out.gz: unexpected end of file

【问题讨论】:

    标签: python streaming zlib gunzip zcat


    【解决方案1】:

    您的 gzip 标头是错误的(8 个字节而不是 10 个),并且您使用一个使用不同标头和尾标的 zlib 流跟踪它。即使您有正确的 gzip 标头,并且如果您有原始的 deflate 流而不是 gzip 流,您仍然不会编写 gzip 预告片。

    要正确执行此操作,请不要尝试编写自己的 gzip 标头。而是请求 zlib 写入一个完整的 gzip 流,这将写入正确的标头、压缩数据和预告片。您可以通过将31wbits 值提供给compressobj() 来做到这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      • 1970-01-01
      • 2020-07-17
      • 2011-01-12
      相关资源
      最近更新 更多