Pythonで作る!分割して自動でZIP化するファイル整理ツール📦
はじめに
「たくさんのファイルをまとめて送りたいけど、1つのZIPファイルだと重すぎる...」
「手作業でファイルを圧縮するのが面倒...」
そんな悩みを解決するツールを、今回はPythonで作っていきます。
プログラミング初心者の方でも理解できるように、基礎から丁寧に解説していきますので、ぜひ最後までお付き合いください!
このツールは何ができるの?
まず、このツールが何をしてくれるのか、具体例で見てみましょう。
たとえば、フォルダの中に50個の写真ファイルがあるとします:
写真1.jpg
写真2.jpg
写真3.jpg
...(たくさんの写真)
写真50.jpg
このツールを使うと、これらが自動的に10個ずつに分けられて、以下のようなZIPファイルができあがります:
archive_1.zip(写真1~写真10が入っています)
archive_2.zip(写真11~写真20が入っています)
archive_3.zip(写真21~写真30が入っています)
archive_4.zip(写真31~写真40が入っています)
archive_5.zip(写真41~写真50が入っています)
この機能には、以下のような特徴があります:
- マウスで操作できる画面付き(専門的にはGUIと呼びます)
- フォルダを選ぶだけの簡単操作
- エラーが起きても安全に停止する機能付き
- 追加でソフトをインストールする必要なし
必要な準備
このツールを動かすために必要なのは、Pythonだけです!
以下のライブラリは、Pythonに最初から入っているので、追加でインストールする必要はありません:
import os # ファイルやフォルダを扱うための機能
import zipfile # ZIPファイルを作るための機能
from pathlib import Path # フォルダやファイルの場所を扱いやすくする機能
import tkinter as tk # 画面(GUI)を作るための機能
from tkinter import filedialog, messagebox # フォルダを選ぶ画面を作る機能
import traceback # エラーが起きたときの情報を詳しく表示する機能
コードを詳しく解説!
1. ファイルをZIPにまとめる部分
まずは、一番重要な「ファイルをZIPにまとめる」部分を見ていきましょう:
def zip_files_in_groups(input_folder, output_folder, files_per_zip=10):
# フォルダの場所を扱いやすい形式に変換
input_path = Path(input_folder)
output_path = Path(output_folder)
# フォルダの中からファイルの一覧を取得
all_files = [f for f in input_path.iterdir() if f.is_file()]
# ファイルを10個ずつ処理していく
for i in range(0, len(all_files), files_per_zip):
# ZIPファイルの名前を決める(例:archive_1.zip)
zip_name = f"archive_{i // files_per_zip + 1}.zip"
zip_path = output_path / zip_name
# ZIPファイルを作って、中にファイルを入れていく
with zipfile.ZipFile(zip_path, 'w') as zipf:
for file in all_files[i:i + files_per_zip]:
zipf.write(file, file.name)
このコードは、以下のような手順で動いています:
-
フォルダの場所を設定
-
Path(input_folder)
で、入力フォルダの場所を指定 -
Path(output_folder)
で、作成したZIPファイルを保存する場所を指定
-
-
ファイルの一覧を取得
-
input_path.iterdir()
で、フォルダの中身を順番に見ていく -
if f.is_file()
で、フォルダではなくファイルだけを選ぶ
-
-
10個ずつグループ化
-
range(0, len(all_files), files_per_zip)
で、10個ずつ区切る - たとえば50個のファイルなら、0-9、10-19、20-29、30-39、40-49の5グループに分ける
-
-
ZIPファイルの作成
-
zipfile.ZipFile(zip_path, 'w')
で新しいZIPファイルを作る -
zipf.write(file, file.name)
で、ファイルをZIPの中に入れる
-
2. フォルダを選ぶ画面の部分
次は、フォルダを選ぶための画面を作る部分です:
def select_folder(title):
try:
# 画面を準備
root = tk.Tk()
root.withdraw() # 余計な画面を隠す
# フォルダを選ぶ画面を表示
folder_path = filedialog.askdirectory(title=title)
return folder_path
except Exception as e:
# エラーが起きたときの処理
print(f"フォルダ選択中にエラーが発生しました: {str(e)}")
print(traceback.format_exc())
return None
この部分は、以下のような働きをします:
-
画面の準備
-
tk.Tk()
で、画面の土台を作る -
root.withdraw()
で、必要のない画面を隠す
-
-
フォルダ選択画面の表示
-
filedialog.askdirectory
で、フォルダを選ぶ画面を表示 - 選んだフォルダの場所が
folder_path
に保存される
-
-
エラー対策
-
try:
とexcept:
で、エラーが起きたときの対策をする - エラーが起きたら、その内容を画面に表示
-
3. メインの処理部分
最後に、全体の流れを管理する部分を見ていきましょう:
def main():
try:
print("GUIを初期化中...")
root = tk.Tk()
root.withdraw()
print("入力フォルダを選んでください...")
input_folder = select_folder("ZIPにしたいファイルがあるフォルダを選択")
if not input_folder:
print("フォルダが選択されませんでした")
return
print("保存先フォルダを選んでください...")
output_folder = select_folder("ZIPファイルを保存するフォルダを選択")
if not output_folder:
print("フォルダが選択されませんでした")
return
print("ZIP作成を開始します...")
zip_files_in_groups(input_folder, output_folder)
print("完了しました!")
messagebox.showinfo("完了", "ファイルのZIP化が完了しました")
except Exception as e:
error_message = f"エラーが発生しました: {str(e)}\n\n{traceback.format_exc()}"
print(error_message)
messagebox.showerror("エラー", error_message)
この部分は、以下の順番で動きます:
-
準備
- 画面の準備をする
- 途中でエラーが起きた場合の対策をする
-
フォルダの選択
- ZIPにしたいファイルがあるフォルダを選んでもらう
- ZIPファイルを保存するフォルダを選んでもらう
-
ZIP作成
- 選んだフォルダの中のファイルをZIP化
- 完了したら知らせる
-
エラー対策
- 問題が起きたら、分かりやすいメッセージを表示
使い方の手順
- プログラムを実行します
- 「ZIPにしたいファイルがあるフォルダを選択」という画面が表示されます
- フォルダを選んで「OK」をクリック
- 「ZIPファイルを保存するフォルダを選択」という画面が表示されます
- 保存先のフォルダを選んで「OK」をクリック
- 自動的にZIPファイルが作られます
- 「完了しました!」というメッセージが表示されます
こんなときはどうする?(よくある質問)
Q1: エラーが表示されました。どうすればいいですか?
A1: エラーメッセージをよく読んで、以下を確認しましょう:
- フォルダは正しく選べていますか?
- フォルダの中にファイルはありますか?
- 選んだフォルダに書き込み権限はありますか?
Q2: なぜ10個ずつに分けるのですか?
A2: 10個は一般的に扱いやすい数として設定していますが、この数は変更できます。
Q3: 日本語のファイル名でも大丈夫ですか?
A3: はい、問題なく処理できます。
できることを増やすヒント(上級者向け)
このツールは、以下のように機能を追加できます:
- 1つのZIPファイルに入れるファイル数を変更
# 20個ずつにしたい場合
zip_files_in_groups(input_folder, output_folder, files_per_zip=20)
- 特定の種類のファイルだけを選ぶ
# 写真(.jpg)だけを選ぶ場合
all_files = [f for f in input_path.iterdir() if f.is_file() and f.suffix == '.jpg']
注意点
- 同じ名前のZIPファイルがある場合は上書きされます
- とても大きなファイルの場合は、処理に時間がかかることがあります
- パソコンのメモリ(作業領域)に余裕があるか確認しましょう
まとめ
このツールを使うことで、以下のことが簡単にできるようになります:
- 大量のファイルを自動的に整理
- 手作業での圧縮作業から解放
- メールで送りやすい大きさのZIPファイルを作成
特に以下のような場面で役立ちます:
- たくさんの写真をまとめるとき
- 仕事の資料を整理するとき
- メールで大量のファイルを送るとき
ぜひこのツールを使って、効率的なファイル管理を実現してください!分からないことがあれば、コメント欄でお気軽に質問してくださいね😊
コード全文
import os
import zipfile
from pathlib import Path
import tkinter as tk
from tkinter import filedialog, messagebox
import traceback
def zip_files_in_groups(input_folder, output_folder, files_per_zip=10):
input_path = Path(input_folder)
output_path = Path(output_folder)
all_files = [f for f in input_path.iterdir() if f.is_file()]
for i in range(0, len(all_files), files_per_zip):
zip_name = f"archive_{i // files_per_zip + 1}.zip"
zip_path = output_path / zip_name
with zipfile.ZipFile(zip_path, 'w') as zipf:
for file in all_files[i:i + files_per_zip]:
zipf.write(file, file.name)
print(f"Created {zip_name} with {min(files_per_zip, len(all_files) - i)} files")
def select_folder(title):
try:
root = tk.Tk()
root.withdraw() # メインウィンドウを非表示にする
folder_path = filedialog.askdirectory(title=title)
return folder_path
except Exception as e:
print(f"フォルダ選択中にエラーが発生しました: {str(e)}")
print(traceback.format_exc())
return None
def main():
try:
print("GUIを初期化中...")
root = tk.Tk()
root.withdraw()
print("入力フォルダの選択ダイアログを表示中...")
input_folder = select_folder("入力フォルダを選択してください")
if not input_folder:
print("入力フォルダが選択されませんでした。")
return
print("出力フォルダの選択ダイアログを表示中...")
output_folder = select_folder("出力フォルダを選択してください")
if not output_folder:
print("出力フォルダが選択されませんでした。")
return
print("ZIP処理を開始します...")
zip_files_in_groups(input_folder, output_folder)
print("ZIP処理が完了しました。")
messagebox.showinfo("完了", "ファイルのZIP化が完了しました。")
except Exception as e:
error_message = f"処理中にエラーが発生しました: {str(e)}\n\n{traceback.format_exc()}"
print(error_message)
messagebox.showerror("エラー", error_message)
if __name__ == "__main__":
main()
input("Enterキーを押して終了してください...")
Discussion