Python zipファイルの圧縮と展開

Python学習【365日チャレンジ!】98日目のマスターU(@Udemy11)です。

突然ですが、コーヒーってインスタント派ですか? 豆から挽く派ですか? それともドルチェ派ですか?

私は、豆から挽いてエスプレッソメーカーで淹れたエスプレッソに泡立てたミルクを加えて作るラテ派です。

エスプレッソメーカー ラテ スタバ並

コーヒーを淹れるのが少し面倒なんですが、スタバで飲むようなラテができるので、高いお金を払ってカフェでラテが飲めなくなります。

豆も挽いてあるものではなく、豆のままで購入しているのですが、楽天市場なら、電動ミル付きでお得な豆も売っているので、超おすすめですよ!

コーヒー豆 電動ミル付き

おいしいコーヒーを飲みながらのPython学習は最高ですよ!

昨日の復習

昨日は、tarファイルの取扱について学習しました。

tarファイルは、ファイルやフォルダをひとまとめにしたもので、アーカープファイルとも言われています。

さらにgzip形式で圧縮することでtar.gzを作ることができ、作ったtar.gzファイルを展開したり、展開せずに中身を確認することができました。

import os
import tarfile


os.mkdir('targz_dir')
os.mkdir('targz_dir/sub_dir')

with open('targz_dir/test.txt', 'w+') as f:
    f.write('This is test')

with open('targz_dir/sub_dir/sub.txt', 'w+') as fsub:
    fsub.write('sub file')

with tarfile.open('test.tar.gz', 'w:gz') as tr:
    tr.add('targz_dir')

このコードは、下記の階層のtargz_dirフォルダを作って、test.tar.gzファイルに圧縮しています。

フォルダ構造

targz_dir ┳ test.txt
          ┗ sub_dir ━ sub.txt

圧縮したtar.gzファイルを展開するためのメソッドには、extractallがあって、extractfileメソッドを使えば、展開せずにファイルの中身を確認することができました。

tarファイルの圧縮展開については、昨日の記事を参考にしてください。

今日は、zipファイルの圧縮展開を学習します。

zipfileライブラリ

zipファイルに圧縮するためには、zipfileライブラリを使います。

昨日学習したtarファイルとは微妙に違うところがありますが、だいたい同じような感じなので、理解は早いかもしれません。

今日は、昨日作成したフォルダ名をtest_dirに変更して、zipファイルに圧縮します。

フォルダ構造

test_dir ┳ test.txt
         ┗ sub_dir ━ sub.txt
import zipfile


with zipfile.ZipFile('test.zip', 'w') as z:
    z.write('test_dir')
    z.write('test_dir/test.zip')
    z.write('test_dir/sub_dir')
    z.write('test_dir/sub_dir/sub.txt')

zipfileライブラリだけだと、ファイルの中にあるすべてのフォルダとファイルをパスで指定する必要があります。

4行目のz.write('test_dir')だけしか記述していなければ、空のtest_dirフォルダだけが入ったtest.zipができてしまいます。

で、登場するのが、ファイル操作で学習したglobライブラリです。

ちょっとの工夫で一気に圧縮

globライブラリは、globメソッドを使うことでフォルダ内のファイルをパスも含めてリスト化することができました。

今回は、さらに一工夫加えることで、一気にzipファイルに書き込みます。

import glob
import zipfile


with zipfile.ZipFile('test.zip', 'w') as z
    for i in glob.glob('test_dir/**', recursive=True):
        r.write(i)

*(アスタリスク一つ)だと、そのフォルダ内のファイルやフォルダだけを参照しますが、**(アスタリスク2つ)をつけることで、下位層のフォルダ内も参照することができます。

recursiveは、「帰納的な、反復的な」という意味で、繰り返し行うためにTrueに指定しています。

forループで、ファイルを一つづつ書き込んでいるということですね。

zipファイルの展開

tarファイルの展開同様に、zipファイルの展開もextractallメソッドを使うことができます。

import zipfile


with zipfile.ZipFile('test.zip', 'r') as z:
    z.extractall()

extractallメソッドに引数を指定しなければ、同じ階層にtest_dirが展開されます。

引数にフォルダ名を指定して、その中にtest_dirを展開することもできます。

展開せずに中身を確認

これまたtarファイルと同じように、zipファイルも、展開せずに中のファイルを確認することができますが、tarライブラリにあったextractfileメソッドは実装されていません。

なので、普通にopenメソッドを使って、中のファイルを読み込みます。

import zipfile


with zipfile.ZipFile('test.zip', 'r') as z:
    with z.open('test_dir/sub_dir/sub.txt', 'r') as f:
        print(f.read())

出力結果

b'sub file'

tarファイルのときと同じように、最下層にあるsub.txtの中身がb(byte)として出力されます。

zipよりtar?

私は、Windowsも使いますが、基本的にMacユーザーなので、zipファイルよりもtar.gzファイルの方が馴染みがあり、なぜなんだろうと思っていたのですが、その訳がわかったような気がします。

tarファイルとzipファイルを両方学習してみると、若干zipファイルのほうが圧縮に手間がかかります。

Windowsユーザーには、zipファイルのほうが一般的なので、Macユーザーも仕方なしに使っていたという感じなのかもしれませんね。

とはいえ、すべてのPCユーザーを対象とする場合は、やっぱりzipファイルのほうがいいのかもしれません。

それでは、今日はこのへんで。

明日も元気にGood Python!