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()

本WebサイトはcookieをPHPのセッション識別および左欄目次の開閉状況記憶のために使用しています。同意できる方のみご覧ください。More information about cookies
programming/python/packages/zipfile.txt · 最終更新: 2018/02/16 by ikatakos
CC Attribution 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0