【python】zipの圧縮・解凍・追加について[zipfileライブラリ]

2020年3月31日

pythonでファイルを圧縮する方法の一つとしてzipfileライブラリの使用が考えられます。
このライブラリはデフォルトで付いているので、追加のインストールは必要ありません。

基本的に下記2点はzipfileライブラリで実施することはできません。やりたい場合は他のライブラリの使用を検討してください。
 ・パスワード付きのzipファイルを作成することは出来ない。
 ・フォルダを丸ごと圧縮すること。不可能ではありませんが手間がかかります。(他ライブラリなら一発の為。)

ライブラリを使用するのでインポートが必要です。
下記の方法でzipfileライブラリをインポートします。

import zipfile

ファイルを扱うので安全のためにwithを使用しましょう。

with zipfile.ZipFile( 【ファイル名】, 【書き込みモード】, 【圧縮方式】) as zf:
    【処理1】
    【処理2】
     ・・・

ファイル名は作成しないzipファイル名です。

読み込みモードは三種類存在します。str型で指定しましょう。

読み込みモード 内容
w書き込み専用(zipファイル作成)
r読み取り専用
a追記(既存のzipファイルに追記)

圧縮方式ですが今回は普通のzipファイルを作成するため「zipfile.ZIP_DEFLATED」を使用します。
下記4種類を指定することができます。

定義内容
zipfile.ZIP_STOREDファイルをまとめるだけで圧縮しない
zipfile.ZIP_DEFLATEDzipファイルで通常の圧縮を行う。
zipfile.ZIP_BZIP2BZIP2形式での圧縮
zipfile.ZIP_LZMALZMA形式での圧縮

ファイルの圧縮を行う。

ファイルの書き込みにはwrite関数を使用します。 読み込みモードは"w"を使用します。
write関数は一回呼び出すごとに1ファイルを圧縮することができます。
なので、複数ファイルを同時圧縮するときはファイル数分のwrite関数を呼び出すこと必要があります。

with zipfile.ZipFile( 【ファイル名】, 【書き込みモード】, 【圧縮方式】) as 【クラス】:
    【クラス】.write(【圧縮したいファイルパス】,arcname=【圧縮先ファイルパス(指定しない場合は元の階層を維持)】)

実際にzipを書き込みモード作成したコードが下記です。
今回はwrite関数で第1引数だけ指定した時と第1,2の引数の両方を指定した時の物を見ていきましょう。

import zipfile

with zipfile.ZipFile( "test1.zip", "w", zipfile.ZIP_DEFLATED) as zf:
    print( type(zf) )
    zf.write( "test/aaa.txt")
    zf.write( "test/bbb.txt", arcname="bbb/111.txt")

圧縮元フォルダ

test
  ├─aaa.txt
  └─bbb.txt

圧縮結果

test1.zip
 ├─bbb
 │   └─111.txt
 └─test
     └─aaa.txt

書き込みについてのソースコードはこちらから

zipファイルへの追記方法について

追記でも書き込みと同じようにwrite関数を使用してファイルの追記を行います。
write関数の使用方法としては書き込み時と変わりありません。
書き込み時との変化は読み込みモード が"a"(追記)となることだけです。

下記の実行例では既存のzipファイル「test1.zip」に対してファイル「test/111.txt」の追記を行います。

import zipfile

with zipfile.ZipFile( "./test1.zip", "a", zipfile.ZIP_DEFLATED) as zf:
    zf.write( "test/111.txt")

追記前

test1.zip
 └─test1
      └─aaa.txt
      └─bbb.txt
      └─ccc.txt

追記後

test1.zip
 ├─test
 │    └─111.txt
 └─test1
      └─aaa.txt
      └─bbb.txt
      └─ccc.txt

追記のソースコードはこちらから

zipファイルの解凍でできること

zipファイルの読み取りでは下記が可能です。
・ファイルの全展開
   関数 : extractall()
・1ファイルの展開
   関数 : extract()
・ファイルの直接読み込み(バイトデータ取得)
    関数 : read()
・ファイル展開時のパスワードを指定
    関数 : setpassword()
・zipファイルに格納されたファイルの一覧を取得する
    関数 : printdir()

読み込みモードは"r"を指定します。

zipファイルを全展開する方法

zipファイルを全展開は「extractall」を使用します。第一引数で展開先のファイルパスの指定が可能です。
引数を入れない場合はカレントディレクトリに解凍されます。

import zipfile

with zipfile.ZipFile( "./test1.zip", "r", zipfile.ZIP_DEFLATED) as zf:
    zf.extractall()

zipファイルの中身を1ファイルずつ展開する

ファイルを一つずつ指定して解凍します。
もちろんextract関数は何度でもコールOKです。

import zipfile

with zipfile.ZipFile( "./test2.zip", "r", zipfile.ZIP_DEFLATED) as zf:
    zf.extract("test2/aaa.txt")
    zf.extract("test2/bbb.txt")

zipファイル内のファイル内容を見る

read関数をコールすることでファイルの中身を見ることができます。

import zipfile

with zipfile.ZipFile( "./test2.zip", "r", zipfile.ZIP_DEFLATED) as zf:
    print( zf.read("test2/aaa.txt") )
    print( zf.read("test2/bbb.txt") )

下記がファイルデータの表示結果です。2つのテキストファイルの中身を表示しています。
str型でなくバイト型となっています。

b'aaa'
b'bbb'

zipファイル内のファイル一覧を表示する

printdir関数を実行することでzipファイル内のファイル一覧を表示できます。

import zipfile

with zipfile.ZipFile( "./test1.zip", "r", zipfile.ZIP_DEFLATED) as zf:
    print( zf.printdir() )#ファイル一覧表示

実行結果

File Name                                             Modified             Size
test1/aaa.txt                                  2020-03-14 16:54:58            3
test1/bbb.txt                                  2020-03-14 16:55:02            3
test1/ccc.txt                                  2020-03-14 16:55:06            3

zipファイルフォルダ解凍(パスワード付き)

zipファイルはパスワードを付けることができます。
setpassword関数を使用することであらかじめパスワードを設定することでその後の処理でパスワードを個々の処理で設定する必要が無くなります。

パスワードを setpassword関数に渡すときに大事なことはstr型でなくバイト型で渡すことです。(つまづきポイント)

import zipfile

pwd = b"pass"
with zipfile.ZipFile( "./test_pass.zip", "r", zipfile.ZIP_DEFLATED) as zf:
    zf.setpassword(pwd)
    zf.extractall()

ソースコードはこちら型から