deflate
-- DEFLATE 圧縮と展開¶
このモジュールは DEFLATE algorithm アルゴリズム(zlib ライブラリや gzip アーカイバで使われている)を使ってバイナリデータの圧縮と展開を行えます。
利用可能性:
MicroPython v1.21 で追加。
展開:
MICROPY_PY_DEFLATE
ビルドオプションで有効化。デフォルトで "extra features" レベル以上のポートには有効になっています(これはほとんどのボードに該当します)。圧縮:
MICROPY_PY_DEFLATE_COMPRESS
ビルドオプションで有効化。デフォルトで "full features" レベル以上のポートには有効になっています(一般的に、これを有効にするには独自のファームウェアをビルドする必要があります)。
クラス¶
- class deflate.DeflateIO(stream, format=AUTO, wbits=0, close=False, /)¶
このクラスは、ファイル、ソケット、(
io.BytesIO
を含む)ストリームのような任意の ストリーム風 オブジェクトをラップするために使えます。このクラスはストリームそのものであり、標準の read/readinto/write/close メソッドを実装しています。ストリーム はブロッキングストリームである必要があります。ノンブロッキングストリームは現在サポートされていません。
フォーマットは以下で定義された定数のいずれかに設定できますが、デフォルトでは
AUTO
となります。この場合、展開では gzip または zlib ストリームを自動検出し、圧縮では生のストリームを生成します。wbits パラメータは DEFLATE 辞書ウィンドウサイズの底2対数を設定します。たとえば、 wbits を10に設定するとウィンドウサイズが1024バイトになります。有効な値は5から15までの範囲です(対応するウィンドウサイズは32バイトから32kバイトまでです)。
wbits が
0
(デフォルト)に設定されている場合、(wbits が 8 に設定されているかのように)圧縮には256バイトのウィンドウサイズが適用されます。展開に関しては、フォーマットに依存します:RAW
の場合、(wbits が 8 に設定されているかのように)256バイトが適用されます。ZLIB
(または zlib が検出された場合のAUTO
)の場合、zlib ヘッダからの値が適用されます。GZIP
(または gzip が検出された場合のAUTO
)の場合、(wbits が 15 に設定されているかのように)32キロバイトが適用されます
ウィンドウサイズ、zlib、gzip ストリームに関する詳細な情報については、後述する ウィンドウサイズ の注釈を参照してください。
close が
True
に設定されている場合、deflate.DeflateIO
ストリームが閉じられるときに基になるストリームも自動的に閉じられます。これは、別のストリームをラップするdeflate.DeflateIO
ストリームを返し、呼出し元が基になるストリームを管理する必要がない場合に便利です。圧縮が有効にされている場合、指定された
deflate.DeflateIO
インスタンスは読み取りと書き込みの両方をサポートします。たとえば、ソケットのような双方向ストリームをラップでき、両方向の圧縮/展開が可能になります
定数¶
サンプルコード¶
deflate.DeflateIO
の典型的な使用例は、圧縮されたファイルをストレージから読み取ったり書き込んだりすることです:
import deflate
# zlib 圧縮したストリームの書出し(デフォルトウィンドウサイズ256バイトを使用)。
with open("data.gz", "wb") as f:
with deflate.DeflateIO(f, deflate.ZLIB) as d:
# Use d.write(...) etc
# zlib 圧縮したストリームの読込み(ウィンドウサイズを自動検出)。
with open("data.z", "rb") as f:
with deflate.DeflateIO(f, deflate.ZLIB) as d:
# d.read(), d.readinto() などを使用。
deflate.DeflateIO
はストリームなので、たとえば json.dump()
や json.load()
(およびストリームで使えるもの)と一緒に使えます:
import deflate, json
# 辞書を JSON として gzip フォーマットで書き出し。
# ウィンドウサイズは small (64 byte)。
config = { ... }
with open("config.gz", "wb") as f:
with deflate.DeflateIO(f, deflate.GZIP, 6) as f:
json.dump(config, f)
# 辞書に読み戻し。
with open("config.gz", "rb") as f:
with deflate.DeflateIO(f, deflate.GZIP, 6) as f:
config = json.load(f)
元のデータがストリーム形式でない場合、 io.BytesIO
を使ってストリーム形式に変換し、 deflate.DeflateIO
で使えるようにできます:
import deflate, io
# bytes/bytearray 値を展開。
compressed_data = get_data_z()
with deflate.DeflateIO(io.BytesIO(compressed_data), deflate.ZLIB) as d:
decompressed_data = d.read()
# bytes/bytearray 値を圧縮。
uncompressed_data = get_data()
stream = io.BytesIO()
with deflate.DeflateIO(stream, deflate.ZLIB) as d:
d.write(uncompressed_data)
compressed_data = stream.getvalue()
DEFLATE のウィンドウサイズ¶
ウィンドウサイズは、圧縮/展開器がストリーム内でどれだけ以前のデータに遡れるかを制限します。ウィンドウサイズを増やすと圧縮が改善されますが、より多くのメモリが必要になり、処理速度も低下します。
入力ストリームを指定のウィンドウサイズで圧縮した場合、それより小さなウィンドウサイズを使う DeflateIO
は、実際に展開のウィンドウサイズよりも遡って参照している場合に限って、 展開途中で OSError
により失敗します。これは、より小さなウィンドウサイズで展開できる可能性があることを意味します。たとえば、元の非圧縮データがウィンドウサイズよりも小さい場合が、これに該当する自明なケースです。
展開¶
zlib フォーマットには、データを圧縮するのに使ったウィンドウサイズを指定するヘッダが含まれています。これは、このストリームを展開するのに必要な最大のウィンドウサイズを示します。このヘッダの値が指定された wbits 値よりも小さい場合(または wbits が設定されていない場合)、ヘッダの値を適用します。
gzip フォーマットには、ヘッダにウィンドウサイズが含まれておらず、すべての gzip 圧縮器(たとえば gzip ユーティリティや CPython の gzip.GzipFile
の処理系など)は 32kiB の最大ウィンドウサイズを使うと仮定しています。そのため、 wbits パラメータが設定されていない場合、展開器は(wbits に15が設定されているかのように) 32kiB のウィンドウサイズを使います。これは、任意の gzip ストリームを展開するために、少なくともこの程度のRAMが使える必要があることを意味します。ソースデータを決める権限を有しているのであれば、ウィンドウサイズが小さい zlib フォーマットを代わりに使うことを検討してください。
raw フォーマットにはヘッダがないため、ウィンドウサイズに関する情報は含まれていません。 wbits が設定されていない場合、ウィンドウサイズは256バイトにデフォルトで設定され、特定のストリームには十分な大きさでないかもしれません。そのため、raw フォーマットを使う場合は常に明示的に wbits を設定することをお勧めします。
圧縮¶
MicroPython の場合、圧縮のすべてのフォーマットに対してデフォルトでウィンドウサイズを256バイトに設定します。これは、最小のメモリ使用量と高速な圧縮時間で、どの展開器でも動作する出力を生成します。