Gzip圧縮・伸張の扱い
Table of contents
Pythonでgzipでの圧縮・伸長(展開/解凍)を行うには組み込みライブラリ gzip
を利用する。
組み込みライブラリなので特に pip install
などで外部のパッケージをインストールしなくても利用できる。
バイト列を圧縮してgzipファイルとして書き込む
write()
などを実装するファイルライクなオブジェクトを作成する gzip.GzipFile()
でGzipFileオブジェクトを書き込みモードで開き, write()
で書き込む。
import gzip
data_to_write = ("本日は晴天なり\n" * 100).encode("utf-8") # encodeしてバイト列として得る
with gzip.GzipFile("./test.txt.gz", "wb") as fh:
# wb = 書き込み(w) + バイナリ(b) モード
fh.write(data_to_write)
fh.flush() # Pythonのバージョンによってはgzipの実装バグで必要なことがある
バイト列をgzip圧縮した結果をバイト列で得る
組み込みライブラリ io
にある io.BytesIO
を使うことでバイト列をgzip圧縮した結果を BytseIO
に書き込み、それを得るとよい。
import gzip
import io
# メモリ上にioできるBytesIOオブジェクトを作成
bytes_io = io.BytesIO()
data_to_write = ("本日は晴天なり\n" * 100).encode("utf-8") # encodeしてバイト列として得る
with gzip.GzipFile(fileobj=bytes_io, mode="wb") as fh:
fh.write(data_to_write)
fh.flush() # Pythonのバージョンによってはgzipの実装バグで必要なことがある
bytes_io.seek(0)
compressed_data = bytes_io.getvalue() # 圧縮されたバイト列(bytes型)
ファイルを圧縮してgzipファイルとして書き込む
読み込みながらgzip圧縮していくことで巨大なファイルも処理できる。
import gzip
source_f = "./sample.txt"
out_f = "./sample.txt.gz"
buf_size = 1024 * 8 # 一度に読み書きする単位(バイト)
with open(source_f, "rb") as in_fh:
with gzip.GzipFile(out_f, "wb") as out_fh:
# 読み込める限り読み込みながらgzip圧縮していく
buf = in_fh.read(buf_size)
while buf != b'':
out_fh.write(buf)
buf = in_fh.read(buf_size)
out_fh.flush() # Pythonのバージョンによってはgzipの実装バグで必要なことがある
# 小さいファイルなら一度にメモリに読み込んでしまうやり方もアリ
with open(source_f, "rb") as in_fh:
# 一度にメモリに読み込む
data = in_fh.read()
# 書き込む(gzip圧縮する)
with gzip.GzipFile(out_f, "wb") as out_fh:
out_fh.write(data)
out_fh.flush() # Pythonのバージョンによってはgzipの実装バグで必要なことがある
gzipファイルを伸張して別のファイルに書き込む
gzip.GzipFile
から読み込みながら普通のファイルに書き込んでいくことでgzipファイルを伸張しファイル保存できる。
import gzip
source_f = "./sample.txt.gz"
out_f = "./sample.txt"
buf_size = 1024 * 8 # 一度に読み書きする単位(バイト)
with gzip.GzipFile(source_f, "rb") as in_fh:
with open(out_f, "wb") as out_fh:
buf = in_fh.read(buf_size) # bufは伸張された状態で出てくる
while buf != b'':
out_fh.write(buf) # 普通のファイルに書き込んでいく
buf = _fh.read(buf_size)
gzipファイルを伸張した結果をバイト列で得る
gzip.GzipFile
から read()
で一気に読み込めばバイト列で得ることができる。
import gzip
source_f = "./sample.txt.gz"
with gzip.GzipFile(source_f, "rb") as fh:
data = fh.read() # dataに一気に読み込んだ伸張されたバイト列が入っている(bytes型)