Python の subprocess.run()
から 7-Zip を呼び出して、フォルダを zip 圧縮するコード例です。
7-Zip はコマンドラインに対応していたので、Python から操作することができました。
7-Zip のバージョン
『7-Zip 19.00 (2019-02-21) for Windows』の『7z1900-x64.exe』を使用しました。
7-Zip 公式サイトのダウンロードページ
https://www.7-zip.org/download.html
OS は Windows 7 64bit です。
7-Zip をインストールしたフォルダにある『7z.exe』を、Python から操作しました。
Python コード例
7z.exe
で『フォルダ』を圧縮する Python コード例です。
コマンドラインの引数リスト args を組み立てて、subprocess.run(args)
で実行しました。
7z.exe
に使える引数は、7-Zip のインストールフォルダにあるマニュアル 7-zip.chm に載っていました。
ところで、7z.exe
はエラーが無くても色々なメッセージを画面に表示したので、subprocess.DEVNULL
でメッセージを出さないようにしました。
7-Zip のマニュアルによると、マルチスレッド設定の引数のデフォルトは -mmt=on
でした。タスクマネージャーを見ていたところ、高い圧縮率を指定した時に、CPU のコアをフルに使用している様子が良く分かりました。-mmt=2
を指定したら、CPU 4コアのうち、2コアだけを使って圧縮してくれました。以下のコード例では、引数をコメントアウトして、デフォルトの動作にしました。
from pathlib import Path
from subprocess import run, DEVNULL
print('start')
# (1/8) 圧縮対象のフォルダを決める
txt_dir = Path(r'F:\apps\data_txt')
# (2/8) 圧縮ファイルの保存フォルダを決める
zip_dir = Path(r'F:\apps\data_zip')
# (3/8) 圧縮ファイルのパスを決める
dst_file = str(zip_dir.joinpath(f'{txt_dir.name}.zip'))
# (4/8) 最上位フォルダを含めるか含めないかを決める
src_dir = f'{txt_dir}\\' # 最上位フォルダを『含める』
# src_dir = f'{txt_dir}\\*' # 最上位フォルダ『無し』
# (5/8) 実行ファイル 7z.exe のファイルパスを決める
exe_file = r'F:\apps\7-Zip\7z.exe'
# (6/8) コマンドラインの引数リストを作る(タプルでもOK)
args = (
exe_file, # 7z.exe
'a', # a (Add) command
dst_file, # 圧縮後のファイル
src_dir, # 圧縮対象フォルダ
'-mx=0', # zipの圧縮率
# -mx=0 (no compression 無圧縮、非圧縮),
# -mx=1 (Fastest),
# -mx=3 (Fast),
# -mx=5 (Normal),
# -mx=7 (Maximum),
# -mx=9 (Ultra 超圧縮)
# '-mmt=on', # multithreading (マルチスレッディング)
# -mmt=on
# -mmt=off
# -mmt=1
# -mmt=2
# -mmt=3
# -mmt=4
# -mmt={N}
)
# (7/8) 圧縮を実行
# subprocess.DEVNULL で 7z.exe のメッセージを抑制。
# cp は CompletedProcess の略です。
cp = run(args, stdout=DEVNULL)
# (8/8) もし 7z.exe がエラーを返したときは知らせる
if cp.returncode != 0:
print(f'error {cp.returncode}')
print('デバッグ')
print(f'(exe_file) {exe_file}')
print(f'(dst_file) {dst_file}')
print(f'(src_dir) {src_dir}')
print(f'(cp.returncode) {cp.returncode}')
# (終了)
print('end')
実行結果
data_txt.zip
という圧縮ファイルができました。
コマンドプロンプトの表示
stdout=DEVNULL
を指定したので、デバッグ用に書いた情報だけが出力されました。
start
デバッグ
(exe_file) F:\apps\7-Zip\7z.exe
(dst_file) F:\apps\data_zip\data_txt.zip
(src_dir) F:\apps\data_txt\
(cp.returncode) 0
end
以下は、stdout=DEVNULL
を指定しなかった場合の表示です。あと、圧縮率の設定を -mx=9 に変更しました。
動作の詳細とともに、『Everything is Ok』と表示されました。
start
7-Zip 19.00 (x64) : Copyright (c) 1999-2018 Igor Pavlov : 2019-02-21
Scanning the drive:
3 folders, 6 files, 40698 bytes (40 KiB)
Creating archive: F:\apps\data_zip\data_txt.zip
Add new data to archive: 3 folders, 6 files, 40698 bytes (40 KiB)
Files read from disk: 6
Archive size: 1925 bytes (2 KiB)
Everything is Ok
デバッグ
(exe_file) F:\apps\7-Zip\7z.exe
(dst_file) F:\apps\data_zip\data_txt.zip
(src_dir) F:\apps\data_txt\
(cp.returncode) 0
end
このままだと、コマンドラインの画面がどんどん流れていってしまいました。なので、表示は出さないようにしたほうが便利でした。
最上位のフォルダを含めた zip ファイル
圧縮対象フォルダのパス文字列の末尾を『バックスラッシュ』にしたら、最上位のフォルダを含んだ zip ファイルができました。
最上位のフォルダを含めなかった zip ファイル
圧縮対象フォルダのパス文字列の末尾を『バックスラッシュとアスタリスク』にしたら、最上位のフォルダを含まない zip ファイルができました。
余計なフォルダを入れずに、圧縮対象フォルダの直下から圧縮することができました。
シンプルな zip ファイルを作りたいときに使っています。
圧縮率を上げた場合の zip ファイル
圧縮率は -mx=[0,1,3,5,7,9]
という引数で変更できました(zip 形式の場合)。
Python マニュアル
コード例で使用した Python ニュアルの場所です。
(Python) class subprocess.CompletedProcess
コンプリーテッドプロセス(args, returncode, stdout, stderr などが取得できる)
(Python) subprocess(新規定数 DEVNULL、プラットフォームに依存しない方法で出力を抑制する)What’s New In Python 3.3
(Python) class pathlib.Path(*pathsegments)
パス
r から始まる文字列 r''
は、 raw strings と呼ばれるもの。
f から始まる文字列 f''
は、f-string とか、フォーマット済み文字列リテラル とか呼ばれるもの。
7-Zip マニュアル
7z.exe
で使用できるコマンドライン引数が載っていた場所です。
7-Zip のインストールフォルダにある 7-zip.chm に載っていました。
7-zip.chm ⇒ command line version ⇒ Syntax(7z.exe
のコマンドライン構文)
7-zip.chm ⇒ command line version ⇒ Exit Codes(7z.exe
の戻り値の意味。0 がエラー無し)
7-zip.chm ⇒ command line version ⇒ Commands ⇒ a (Add)(アーカイブにファイル群を追加する)
7-zip.chm ⇒ command line version ⇒ Switches ⇒ -m (Set compression Method) switch(『圧縮率の設定方法』や『マルチスレッドの設定方法』など)
以上です。