2

Python でbz2and/orパッケージを使用しようとしています。lzmaデータベース ダンプを csv 形式で圧縮してファイルに保存しようとしていzipます。両方のパッケージでワンショット圧縮で動作するようになりました。

コードは次のようになります。

with ZipFile('something.zip', 'w') as zf:
    content = bz2.compress(bytes(csv_string, 'UTF-8'))  # also with lzma
    zf.writestr(
        'something.csv' + '.bz2',
        content,
        compress_type=ZIP_DEFLATED
    )

増分圧縮を使用しようとすると、.zip ファイルが作成され、抽出しようとすると、いくつかのアーカイブ ファイルが再帰的に提供され続けます。

コードは次のようになります。

with ZipFile('something.zip', 'w') as zf:
    compressor = bz2.BZ2Compressor()
    content = compressor.compress(bytes(csv_string, 'UTF-8'))  # also with lzma
    zf.writestr(
        'something.csv' + '.bz2',
        content,
        compress_type=ZIP_DEFLATED
    )
    compressor.flush()

ドキュメントを調べ、圧縮技術に関する情報も探しましたが、ワンショット圧縮とインクリメンタル圧縮とは何かについての包括的な情報はないようです。

4

1 に答える 1

6

ワンショットとインクリメンタルの違いは、ワンショット モードではデータ全体をメモリに格納する必要があることです。100 ギガバイトのファイルを圧縮する場合は、大量の RAM が必要です。

インクリメンタル エンコーダーを使用すると、コードは一度に 1 メガバイトまたは 1 キロバイトずつコンプレッサーに供給し、データが利用可能になるとすぐに、その結​​果をファイルに書き込むことができます。もう 1 つの利点は、データのストリーミングに使用できるインクリメンタル コンプレッサです。すべての非圧縮データが利用可能になる前に、圧縮データの書き込みを開始できます。


2 番目のコードが間違っているため、データが失われます。はflush、保存する必要があるさらに多くのデータを返す場合もあります。'a'ここでは、Python 3で 1000 文字の文字列を圧縮しています。からの結果compressは空の文字列です。から実際の圧縮データが返されflushます。

>>> c = bz2.BZ2Compressor()
>>> c.compress(b'a' * 1000)
b''
>>> c.flush()
b'BZh91AY&SYI\xdcOc\x00\x00\x01\x81\x01\xa0\x00\x00\x80\x00\x08 \x00 
\xaamA\x98\xba\x83\xc5\xdc\x91N\x14$\x12w\x13\xd8\xc0'

したがって、2 番目のコードは次のようになります。

compressor = bz2.BZ2Compressor()
content = compressor.compress(bytes(csv_string, 'UTF-8'))  # also with lzma
content += compressor.flush()    

しかし実際には、非常に複雑な方法でワンショット圧縮を行っています。

于 2015-03-25T15:49:30.473 に答える