Pythonでtar.gzなファイルを解凍(展開)する

Pythonでtar.gzで圧縮されたファイルを解凍(展開)してみます。

目次

  1. tarfileモジュールでtar.gzファイルを扱う
  2. 使用するメソッド
  3. 展開の実施例

tarfileモジュールでtar.gzファイルを扱う

拡張子がtar.gzなファイルというのは、tarというツールでファイルをひとまとめにして、gzipで圧縮したファイルです。

Windowsではzipがメインですが、Linuxがらみのファイルをいじるようになるとダウンロードしたデータがtar.gzになっていることがよくあります。Linuxならgzipで展開できます。Windows10にはtarは標準でインストールされているのですがgzipがありません。

7zipを使えばこのファイルを展開できるのですが、そのためだけに7zipをインストールするのも面倒です。

そこで、Pythonで展開することにしました。

Pythonのtarfileモジュールがtarでgzなファイルの展開に対応しています。標準モジュールなので、Python3が入っていればpipも要りません。

使用するメソッド

tarfile.openメソッド

t = tarfile.open(name, [mode], [fileobj], [bufsize])

変数

内容

name

str

ファイルのパス。

mode

str

省略可。規定値はr。ファイルアクセスするモード。

fileobj

str

省略可。規定値はNone。

bufsize

int

省略可。規定値は10240。

t

TarFile

指定されたファイルパスのTarFileオブジェクト。

modeの例

r

圧縮方法に関して透過的に、読み込み専用にオープンする。

x

圧縮せずにtarfileを作成する。ファイルが既存の場合はエラー。

a

圧縮せずにtarfileを追記用にオープンする。

w

非圧縮で書き込み用にオープンする。

w:gz

gzip圧縮で書き込み用にオープンする。

ファイルをオープンするメソッドです。読み込みでも書き込みでも使います。展開の時はファイルパスだけ指定すればOKですね。

Openで得られたTarFileオブジェクトに対して、展開の操作をします。

TarFile.extractallメソッド

t.extractall([path], [members], [numeric_owner])

変数

内容

t

TarFile

展開の対象となるオープン済みのTarFileオブジェクト。

path

str

省略可。規定値は.。展開先のディレクトリ。

members

list

省略可。規定値はNone。

numeric_owner

bool

省略可。規定値はFalse。

ファイルを展開します。pathを設定しない場合は、作業ディレクトリに展開します。

ここで注意なのは、展開先が作業フォルダ以下に限らないということです。圧縮ファイル内のファイルのパスがルートに指定されている場合は、ルートに展開されます。

そこで、圧縮ファイルに格納されているファイルのパスを調べてみます。

TarFile.getmembersメソッド

L = T.getmenbers()

変数

内容

T

TarFile

展開の対象となるオープン済みのTarFileオブジェクト。

L

list

圧縮ファイルに含まれているメンバーのリストを返します。

戻り値がTarInfoというオブジェクトのリストになります。リスト内の各TarInfoオブジェクトのnameプロパティにアクセスすると、ファイルのパスが得られます。

展開の実施例

展開するときの処理の順番としては、次のようになります。

  1. tarfile.openメソッドでファイルをオープンする。

  2. TarFile.getmenbersメソッドで、圧縮ファイル内のファイルのパスがカレントディレクトリ以下かどうか調べる。

  3. TarFile.extractallメソッドで展開する。

では実際に試してみます。

tar.gzなファイルとしては、onnx model zooからダウンロードしたmnist.tar.gzにしてみます。

import tarfile
with tarfile.open('mnist.tar.gz') as tar:
    for i in tar.getmembers():
        if i.name[0] == '/' or i.name[0:2] == '..':
            print('外のディレクトリに展開されるかも。')
            exit()
    tar.extractall()
>dir /s /b
C:\mnist
C:\mnist.tar.gz
C:\mnist\model.onnx
C:\mnist\test_data_set_0
C:\mnist\test_data_set_1
C:\mnist\test_data_set_2
C:\mnist\test_data_set_0\input_0.pb
C:\mnist\test_data_set_0\output_0.pb
C:\mnist\test_data_set_1\input_0.pb
C:\mnist\test_data_set_1\output_0.pb
C:\mnist\test_data_set_2\input_0.pb
C:\mnist\test_data_set_2\output_0.pb

もうちょっとPython的にエレガントに書く方法がありそうですが、まあ動いたのでよしとします。

公開日

広告