zipfile, tarfile
Zipなどの圧縮・展開用モジュール
7-Zip, WinRARなどの高速なアーカイバがインストール済なら、敢えてこれを使わなくてもsubprocess.run()でそちらを使った方が速いかも。
ただ、圧縮・展開にちょっと細かい条件をつけたい時には重宝。
Zip展開:新しいもののみ上書き
- 展開先に同名の既存ファイルがあれば、更新時刻を比較し、新しければ上書き、同じか古ければスキップ
- zipには、各ファイルの更新時刻が記録されている
from zipfile import ZipFile
src_path = 'src.zip'
tgt_dir = 'C:\\dst'
with ZipFile(src_path, mode='r') as zh:
for zipinfo in zh.infolist():
# zipアーカイブ内のファイルの更新時刻を取得
zip_mtime = datetime.datetime(*zipinfo.date_time).timestamp()
tgt_path = os.path.join(tgt_dir, zipinfo.filename)
if os.path.exists(tgt_path):
# 既存のファイルがあれば更新時刻を取得
tgt_mtime = os.path.getmtime(tgt_path)
# 既存の方が新しかったらスキップ
if tgt_mtime >= zip_mtime:
# 一応、ファイルサイズも出力しとく
tgt_size = os.path.getsize(tgt_path)
zip_size = zipinfo.file_size
print(zipinfo.filename, 'already exists newer one.',
tgt_mtime, zip_mtime, tgt_size, zip_size)
continue
# 展開
zh.extract(zipinfo, tgt_dir)
# ファイル更新時刻とアクセス時刻を更新(そのままだと、展開時の時刻になる)
os.utime(tgt_path, (zip_mtime, zip_mtime))
print(zipinfo.filename, 'extracted.')
tgz展開: ファイル名などで選択して解凍
tarfile.open()で圧縮ファイルを読み込み開始- modeは
rにしとけば、tar, tgz, tbzあたりは自動判定してくれる
TarFile.getmembers()で、圧縮ファイル中のファイルとディレクトリのTarInfoオブジェクトをイテレートTarInfoオブジェクトは、name, size, mtime, isfile, isdirあたりの情報を持ってる- 解凍したいのがあったら、
TarFile.extractfile(TarInfo)で そのファイルのio.BufferedReaderオブジェクトが得られる - 解凍したい場所にバイナリ書き込みで
open()して書き込む
"""
tgzやtbzから、.dbファイルだけを解凍して抽出
"""
import tarfile
import os
gzip_path = 'tmp.tgz'
tgt_dir = 'extract'
def make_parent_dirs(path):
pardir = os.path.dirname(path)
if not os.path.exists(pardir):
os.makedirs(pardir)
def main():
if not os.path.exists(tgt_dir):
os.makedirs(tgt_dir)
with tarfile.open(gzip_path, mode='r') as rh:
for mem in rh.getmembers():
spn = mem.name.split('/')
if spn[-1][-3:] != '.db':
continue
# print(mem)
tgt_path = os.path.join(tgt_dir, mem.name)
make_parent_dirs(tgt_path)
with open(tgt_path, mode='wb') as wh:
wh.write(rh.extractfile(mem).read())
if __name__ == '__main__':
main()

