0

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
4

1 に答える 1

1

gzip ヘッダーが間違っています (10 バイトではなく 8 バイト)。別のヘッダーとトレーラーを使用する zlib ストリームを続けます。正しい gzip ヘッダーがあったとしても、gzip ストリームではなく未加工の deflate ストリームがあったとしても、gzip トレーラーを作成していないことになります。

これを正しく行うには、独自の gzip ヘッダーを作成しようとしないでください。代わりに、zlib に完全な gzip ストリームを書き込むように要求してください。これにより、正しいヘッダー、圧縮データ、およびトレーラーが書き込まれます。これを行うには、 to の値wbitsを指定します。31compressobj()

于 2016-06-21T16:19:35.823 に答える