Pythonでgzipファイルを解凍する

Python
Python

Pythonでgzipファイルを解凍する方法について記載します。gzip圧縮されたログファイル等を扱う際に利用できるかもしれません。

スポンサーリンク

はじめに

gzipファイルを扱う際は共通してgzipを利用しています。標準ライブラリです。
また、今回はPython 3.7を利用して動作確認を行っています。マイナーバージョンが違っても、3系なら動くとは思います。

ファイルに解凍する

gzipファイルを解凍した結果をファイルとして扱いたいケースです。例えば、ファイルのアップロードを行いたい場合や、他処理のインプットがファイル形式の場合等が考えられます。

shutil.copyfileobj()

shutil.copyfileobj()を利用して、読み込んだgzipのファイルオブジェクトを別ファイルとしてコピーする方法です。個人的には一番好きな手法です。

サンプル

import gzip
import shutil

source_file = "file.txt.gz"
target_file = "file.txt"

with gzip.open(source_file, mode="rb") as gzip_file:
    with open(target_file, mode="wb") as decompressed_file:
        shutil.copyfileobj(gzip_file, decompressed_file)

write()

write()を利用して、読み込んだファイルオブジェクトを別ファイルに書き込む方法です。別の情報も併せて書き込みたい時等には役立つかもしれません。

サンプル

import gzip

source_file = "file.txt.gz"
target_file = "file.txt"

with gzip.open(source_file, mode="rb") as gzip_file:
    content = gzip_file.read()
    with open(target_file, mode="wb") as decompressed_file:
        decompressed_file.write(content)

subprocess

subprocessを利用して、OSコマンドから解凍する方法です。自分で実装するより、OSコマンドを利用する方が安心できるという時には良いかもしれません。

サンプル

import subprocess

source_file = "file.txt.gz"

command = ["gunzip", source_file]
subprocess.run(
    command,
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT
)

sh

shを利用して、OSコマンドから解凍する方法です。なお、shは標準ライブラリではないので、別途インストールする必要があります(pipで可能です)。全体の記述行を少しでも減らしたい場合には良いかもしれません。

サンプル

from sh import gunzip

source_file = "file.txt.gz"

gunzip(source_file)

中身を直接読み込む

gzipファイルの中身を直接読み込むケースです。単純にファイルの情報が必要なだけで、解凍されたファイルが欲しいわけではないといった状況が考えられます。

モードでtを指定することでテキストとして、bを指定することでバイナリとして読み込むことができます。

元ファイル

$ cat <<'_EOF_' > file.txt
春は花
夏ほととぎす
秋は月
冬雪さえて
すずしかりけり
_EOF_
$ gzip file.txt

テキストモード

str型で取得することができます。なお、open時にencodingのオプションを利用することで、エンコードモードを指定することもできます。

サンプル

>>> import gzip
>>> 
>>> source_file = "file.txt.gz"
>>> 
>>> with gzip.open(source_file, mode="rt") as gzip_file:
...     content = gzip_file.read()
...     type(content)
...     print(content)
... 
<class 'str'>
春は花
夏ほととぎす
秋は月
冬雪さえて
すずしかりけり

>>> 

バイナリモード

bytes型で取得することができます。今回のサンプルでは文字列をデコードして再表示していますが、もちろん、そのままbytes型で扱うこともできます。

サンプル

>>> import gzip
>>> 
>>> source_file = "file.txt.gz"
>>> 
>>> with gzip.open(source_file, mode="rb") as gzip_file:
...     content = gzip_file.read()
...     type(content)
...     print(content)
...     print(content.decode())
... 
<class 'bytes'>
b'\xe6\x98\xa5\xe3\x81\xaf\xe8\x8a\xb1\n\xe5\xa4\x8f\xe3\x81\xbb\xe3\x81\xa8\xe3\x81\xa8\xe3\x81\x8e\xe3\x81\x99\n\xe7\xa7\x8b\xe3\x81\xaf\xe6\x9c\x88\n\xe5\x86\xac\xe9\x9b\xaa\xe3\x81\x95\xe3\x81\x88\xe3\x81\xa6\n\xe3\x81\x99\xe3\x81\x9a\xe3\x81\x97\xe3\x81\x8b\xe3\x82\x8a\xe3\x81\x91\xe3\x82\x8a\n'
春は花
夏ほととぎす
秋は月
冬雪さえて
すずしかりけり

>>> 

最近、短めの記事が多かったですが、今回は特に短い内容でした。仕事もプライベートも落ち着いたら、もう少し手の込んだものを書きたいです。

コメント

タイトルとURLをコピーしました