iMind Developers Blog

iMind開発者ブログ

Pythonでzipファイルの読み書き

概要

Pythonでzipファイルを生成したり、解凍したり、ストレージに展開せずにzipの中身を読んだり、既存のzipにファイルを追加したり等。

バージョン情報

  • Python 3.7.3

ディレクトリをまとめてアーカイブ

指定ディレクトリをzip圧縮する場合は shutil.make_archive を利用すると便利。

例として下記のようなファイル構成に対して実行してみる。

foo
├── bar.txt
└── baz.txt
import shutil

shutil.make_archive(
    'foo',
    format='zip',
    base_dir='foo')

これでカレントディレクトリに foo.zip が生成される。

make_archiveのformatにはzip以外にもtar, gztar(tar.gz), bztar(tar.bz2), xztar(tar.xz)が指定できる。

zipファイルの生成

make_archiveの逆の動作をするのがunpack_archive。

extract_dirは解凍先のディレクトリ。下記ではfoo2というディレクトリに解凍したファイルが出力される。

shutil.unpack_archive(
    'foo.zip',
    extract_dir='foo2')

zipファイルにファイルを書き込む

Pythonの文字列をzipファイルの中に直接書き込んでみる。

import zipfile

# 書き込む文字列
write_string = 'bar'

with zipfile.ZipFile('foo.zip', 'w', 
        compression=zipfile.ZIP_DEFLATED) as zf:
    # bar.txtをzip fileの中に書き込む
    with zf.open('bar.txt', 'w') as f:
        f.write(write_string.encode())

上記では新規ファイルをzipの中に追加しているが、既存のファイルを入れることもできる。

適当に新規ファイルを作成。

$ echo baz > baz.txt

上記ファイルをzipに加える。

with zipfile.ZipFile('foo.zip', 'w', 
        compression=zipfile.ZIP_DEFLATED) as zf:
    # baz.txtをzip fileの中に書き込む
    zf.write('baz.txt')

zipファイルの解凍

shtutil.unpack_archiveのようにまとめて指定ディレクトリに解凍したい場合は、extractallを使う。

with zipfile.ZipFile('foo.zip') as zf:
    zf.extractall('foo3')

これで foo.zip の内容が foo3 ディレクトリに解凍される。

zipファイルから指定ファイルのみ読む

zipの中から必要なファイルだけ指定して内容を読み込む。

下記はzipの中から foo/bar.txt の内容をprintしている。

with zipfile.ZipFile('foo.zip') as zf:
    # foo/bar.txtの内容を表示
    print(zf.read('foo/bar.txt'))

    # こういう書き方もできる
    with zf.open('foo/bar.txt') as f:
        print(f.read())

zipの中のパス構成を確認する

infolist() で当該zipファイルに含まれるディレクトリ及びファイルの情報(ZipInfo型)が一覧で取れる。

with zipfile.ZipFile('foo.zip') as zf:
    for info in zf.infolist():
        print(info.filename, info.is_dir())

# 出力結果
#=> foo/ True
#=> foo/bar.txt False
#=> foo/baz.txt False

ZipInfoからは、filename, is_dir(), date_time(=最終更新日), compress_type, comment, file_size, compress_size(=圧縮後のファイルサイズ)などが取れる。

既存のzipファイルに新しくファイルを追加する

mode=a にすれば追記が可能。

import zipfile

with zipfile.ZipFile('foo.zip', 'a', 
        compression=zipfile.ZIP_DEFLATED) as zf:

    # bar.txtをzip fileの中に書き込む
    with zf.open('new_file.txt', 'w') as f:
        f.write(b'new file')

これで既存の foo.zip に new_file.txt というファイルが追加された。

改定履歴

Author: Masato Watanabe, Date: 2019-08-17, 記事投稿