Pythonで .tar, .tar.gz, .tgz などのアーカイブファイルを操作するには、標準ライブラリの tarfile モジュールを使用します。
サーバー管理やLinux環境でのデータ交換などで頻繁に利用される形式です。
目次
Tarファイルとは?
「Tar(Tape Archive)」は、複数のファイルを1つのファイルにまとめるアーカイブ形式です。
Tar形式自体にはデータを圧縮する機能はありませんが、通常は gzip や bzip2 などの圧縮形式と組み合わせて使用されます。そのため、拡張子は .tar 単体よりも、.tar.gz や .tar.bz2 となっていることが一般的です。
open関数のモード一覧
tarfile.open() でファイルを開く際に指定できる主な読み込みモードは以下の通りです。
通常は ‘r:*’(自動判別)が使われますが、明示的に指定することも可能です。
| モード文字列 | 意味・用途 |
'r' または 'r:*' | 自動判別読み込み(推奨)。圧縮形式(gzip, bzip2, lzma)を自動的に認識して開きます。 |
'r:gz' | gzip 圧縮されたファイルを読み込みます(拡張子 .tar.gz, .tgz など)。 |
'r:bz2' | bzip2 圧縮されたファイルを読み込みます(拡張子 .tar.bz2, .tbz など)。 |
'r:xz' | lzma (xz) 圧縮されたファイルを読み込みます(拡張子 .tar.xz など)。 |
実装例:サーバーログ(.tar.gz)の展開
ここでは、バックアップされたウェブサーバーのログファイル web_logs_backup.tar.gz を、解析用のディレクトリ log_analysis に展開する処理を実装します。
ソースコード
import tarfile
import os
# 1. 展開対象のファイルと展開先ディレクトリ
archive_path = "web_logs_backup.tar.gz"
extract_to = "log_analysis"
print(f"--- アーカイブ '{archive_path}' を展開します ---")
# 展開先ディレクトリが存在しない場合は作成しておく(エラー防止)
if not os.path.exists(extract_to):
os.makedirs(extract_to)
# 2. tarファイルを開く
# mode="r:gz" でgzip圧縮を明示的に指定("r" だけでも自動判別されます)
# encoding="utf-8" はtar内のファイル名がUTF-8の場合に指定します
try:
with tarfile.open(archive_path, mode="r:gz") as tar:
# 中身のファイル名を表示(確認用)
print("含まれるファイル:")
for member in tar.getnames():
print(f" - {member}")
# 3. 全ファイルを指定ディレクトリに展開
# filter='data' はPython 3.12以降で推奨されるセキュリティ設定です
# (ディレクトリトラバーサル攻撃などを防ぐため)
if hasattr(tarfile, 'data_filter'):
tar.extractall(path=extract_to, filter='data')
else:
# 古いバージョンのPython用
tar.extractall(path=extract_to)
print(f"\n展開が完了しました: {extract_to}/")
except FileNotFoundError:
print(f"エラー: ファイル '{archive_path}' が見つかりません。")
except tarfile.ReadError:
print("エラー: ファイルの形式が無効か、破損しています。")
実行結果
--- アーカイブ 'web_logs_backup.tar.gz' を展開します ---
含まれるファイル:
- access.log
- error.log
- app/debug.log
展開が完了しました: log_analysis/
解説
tarfile.open(name, mode): アーカイブを開きます。withブロックを使うことで、処理終了後にファイルを自動的に閉じます。extractall(path): アーカイブ内のすべてのファイルを、指定したpathに展開します。- セキュリティ(filter=’data’): Python 3.12から、悪意のあるパス(
../../etc/passwdなど)を含むtarファイルを不用意に展開しないよう、filter引数の指定が推奨されています。一般的なデータファイルであればfilter='data'を指定するのが安全です。
