Zipなどの圧縮・展開用モジュール
7-Zip, WinRARなどの高速なアーカイバがインストール済なら、敢えてこれを使わなくてもsubprocess.run()でそちらを使った方が速いかも。
ただ、圧縮・展開にちょっと細かい条件をつけたい時には重宝。
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.')
tarfile.open()
で圧縮ファイルを読み込み開始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()