note.nkmk.me

Pythonでzipファイルを圧縮・解凍するzipfile

Date: 2018-02-04 / tags: Python, ファイル操作
このエントリーをはてなブックマークに追加

Pythonの標準ライブラリzipfileで、ファイルをzipに圧縮したり、zipファイルを解凍したりすることができる。

スポンサーリンク

複数のファイルをzipファイルに圧縮

ZipFileオブジェクトを作成し、write()メソッドで圧縮したいファイルを追加していく。

zipファイルを新規作成する場合は、ZipFileオブジェクトのコンストラクタの第一引数fileに作成するzipファイルのパスを指定し、第二引数mode'w'とする。

さらに、第三引数compressionで圧縮方式を指定できる。

  • zipfile.ZIP_STORED: 圧縮せず複数ファイルをまとめるだけ(デフォルト)
  • zipfile.ZIP_DEFLATED: 通常のZIP圧縮(要zlibモジュール)
  • zipfile.ZIP_BZIP2: BZIP2圧縮(要bz2モジュール)
  • zipfile.ZIP_LZMA: LZMA圧縮(要lzmaモジュール)

BZIP2、LZMAのほうが圧縮率が高い(より小さいサイズに圧縮できる)が、圧縮にかかる時間が長くなる。

write()メソッドでは、第一引数filenameのファイルを第二引数arcnameという名前でzipファイルに書き込む。arcnameは省略するとfilenameがそのまま使われる。

import zipfile

with zipfile.ZipFile('data/temp/new_comp.zip', 'w', compression=zipfile.ZIP_DEFLATED) as new_zip:
    new_zip.write('data/temp/test1.txt', arcname='test1.txt')
    new_zip.write('data/temp/test2.txt', arcname='zipdir/test2.txt')
    new_zip.write('data/temp/test3.txt', arcname='zipdir/sub_dir/test3.txt')

write()メソッドの引数compress_typeを指定することで、ファイルごとに圧縮方式を選択することもできる。

with zipfile.ZipFile('data/temp/new_comp_single.zip', 'w') as new_zip:
    new_zip.write('data/temp/test1.txt', arcname='test1.txt', compress_type=zipfile.ZIP_DEFLATED)
    new_zip.write('data/temp/test2.txt', arcname='zipdir/test2.txt')
    new_zip.write('data/temp/test3.txt', arcname='zipdir/sub_dir/test3.txt')

既存のzipファイルに新たなファイルを追加

既存のzipファイルに新たなファイルを追加するには、ZipFileオブジェクトを作成する際に、コンストラクタの第一引数fileを既存のzipファイルのパス、第二引数mode'a'とする。

あとは上の例と同じく、write()メソッドでファイルを追加すればOK。

with zipfile.ZipFile('data/temp/new_comp.zip', 'a') as existing_zip:
    existing_zip.write('data/temp/test4.txt', arcname='test4.txt')

ディレクトリ(フォルダ)をzipファイルに圧縮

ディレクトリ(フォルダ)をまるごと一つのzipファイルに圧縮する場合、os.scandir()os.listdir()でファイルのリストを作って行うこともできるが、shutilモジュールのmake_archive()を使うほうが簡単。

以下の記事を参照。

パスワード付きのzipファイルに圧縮

zipfileモジュールでは、パスワードで保護されたzipを作成することはできない。ファイルをパスワード付きのzipファイルに圧縮したい場合は、サードパーティのライブラリpyminizipを使う。

なお、パスワード保護されたzipの解凍はzipfileモジュールで行うことが可能(後述)。

zipファイルの中身を確認

既存のzipファイルの中身を確認することができる。

ZipFileオブジェクトを、コンストラクタの第一引数fileを既存のzipファイルのパス、第二引数mode'r'として作成する。引数modeはデフォルトがrなので省略可能。

ZipFileオブジェクトのnamelist()メソッドで、アーカイブされているファイルのリストを取得できる。

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    print(existing_zip.namelist())
# ['test1.txt', 'zipdir/test2.txt', 'zipdir/sub_dir/test3.txt', 'test4.txt']

zipファイルの中身をすべて解凍(展開)

zipファイルの中身を解凍する場合も、上の中身を確認する例と同じく、ZipFileオブジェクトを、コンストラクタの第一引数fileを既存のzipファイルのパス、第二引数mode'r'として作成する。引数modeはデフォルトがrなので省略可能。

ZipFileオブジェクトのextractall()メソッドで、zipファイルの中身がすべて解凍(展開)される。第一引数pathに展開先のディレクトリのパスを指定する。省略するとカレントディレクトリに解凍される。

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extractall('data/temp/ext')

パスワード付きのzipファイルはextractall()メソッドの引数pwdにパスワードを指定すると解凍できる。

with zipfile.ZipFile('data/temp/new_comp_with_pass.zip') as pass_zip:
    pass_zip.extractall('data/temp/ext_pass', pwd='password')

zipファイルの中身を選択して解凍(展開)

ある特定のファイルだけを解凍して取り出したい場合は、extract()メソッドを使う。

extract()メソッドの第一引数に解凍するファイル名、第二引数pathに展開先のディレクトリのパスを指定する。引数pathは省略するとカレントディレクトリに解凍される。

with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extract('test1.txt', 'data/temp/ext2')

extract()メソッドもextractall()メソッドと同様、引数pwdにパスワードを指定できる。

with zipfile.ZipFile('data/temp/new_comp_with_pass.zip') as pass_zip:
    pass_zip.extract('test1.txt', 'data/temp/ext_pass2', pwd='password')
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事