در این مقاله قصد داریم از مفهومی به نام هش برای شناسایی فایل های منحصر به فرد و حذف فایل های تکراری با استفاده از پایتون استفاده کنیم.
ماژول های مورد نیاز:
- tkinter: ما باید راهی برای انتخاب پوشه ای که می خواهیم این فرآیند پاکسازی را در آن انجام دهیم ایجاد کنیم، بنابراین هر بار که کد را اجرا می کنیم باید یک فایل محاوره ای برای انتخاب یک پوشه دریافت کنیم و از کتابخانه Tkinter استفاده کنیم. در این کتابخانه، ما متدی به نام “askdirectory” داریم که میتوان از آن برای درخواست از کاربر برای انتخاب دایرکتوری استفاده کرد. برای نصب این کتابخانه، دستور زیر را در IDE/terminal تایپ کنید.
pip install tk
- hashlib: برای استفاده از تابع hashlib md5 به کتابخانه hashlib نیاز داریم. برای نصب این کتابخانه، دستور زیر را در IDE/terminal تایپ کنید.
pip install hashlib
- os: این ماژول با ارائه توابعی برای واکشی محتویات فایل و حذف فایل ها و غیره به ما در حذف فایل های تکراری کمک می کند. برای نصب این کتابخانه، دستور زیر را در IDE/terminal تایپ کنید. ماژول os بخشی از کتابخانه استاندارد در پایتون است.
رویکرد:
- ما از کاربر می خواهیم که یک پوشه را انتخاب کند و همه فایل های تکراری و اضافی را در زیر این دایرکتوری چتر جستجو می کنیم.
- ما محتوای هر فایل را می گیریم و آن را از طریق یک تابع هش عبور می دهیم که یک رشته منحصر به فرد مربوط به یک فایل منحصر به فرد ایجاد می کند.
- رشته هش یک اندازه ثابت خواهد بود و اندازه آن به نوع تابع هش که استفاده می کنیم بستگی دارد. ما توابع هش زیادی مانند md5، SHA1 یا SHA 256 و بسیاری دیگر داریم. در این مقاله، ما از هش md5 استفاده خواهیم کرد و همیشه یک مقدار هش 32 کاراکتری تولید می کند، صرف نظر از اندازه فایل و نوع فایل.
- به منظور شناسایی فایل های تکراری و سپس حذف آن فایل ها، ما قصد داریم یک فرهنگ لغت پایتون را حفظ کنیم.
- ما می خواهیم رشته هش هر فایل را به عنوان کلیدهای فرهنگ لغت و مسیرهای فایل به عنوان مقادیر فرهنگ لغت در هر زیرپوشه دایرکتوری ریشه ارسال کنیم.
- هر بار که یک رکورد فایل جدید را وارد می کنیم، بررسی می کنیم که آیا ورودی های تکراری در فرهنگ لغت خود دریافت می کنیم یا خیر. اگر فایل تکراری پیدا کنیم مسیر فایل را می گیریم و آن فایل را حذف می کنیم.
پیاده سازی مرحله ای
مرحله 1: کتابخانه های Tkinter، os، hashlib و pathlib را وارد کنید.
from tkinter.filedialog import askdirectory
from tkinter import Tk
import os
import hashlib
from pathlib import Path
مرحله 2: ما از tk.withdraw استفاده می کنیم زیرا نمی خواهیم پنجره رابط کاربری گرافیکی tkinter روی صفحه نمایش ما ظاهر شود، ما فقط می خواهیم گفتگوی فایل را برای انتخاب پوشه انتخاب کنیم. askdirectory(title=”Select a folder”) این خط کد یک کادر محاوره ای روی صفحه ظاهر می شود که از طریق آن می توانیم یک پوشه را انتخاب کنیم.
Tk().withdraw()
file_path = askdirectory(title="Select a folder")
مرحله 3: در مرحله بعد باید تمام فایل های داخل پوشه ریشه خود را لیست کنیم. برای انجام این کار به ماژول سیستم عامل نیاز داریم، os.walk() مسیر پوشه ریشه ما را به عنوان آرگومان می گیرد و از هر زیر شاخه پوشه ای که به آن داده شده است عبور می کند و تمام فایل ها را لیست می کند. این تابع لیستی از تاپل ها را با سه عنصر برمی گرداند. عنصر اول مسیر آن پوشه و عنصر دوم تمام زیر پوشه های داخل آن پوشه و عنصر سوم لیستی از تمام فایل های داخل آن پوشه است.
list_of_files = os.walk(file_path)
مرحله 4: هدف نهایی ما فهرست کردن همه فایل ها در هر زیر شاخه و دایرکتوری اصلی است، به همین دلیل است که ما یک حلقه for را روی همه فایل ها اجرا می کنیم. برای انجام این کار باید هر فایلی را باز کنیم و آن را به یک رشته هش تبدیل کنیم تا متغیری به نام hash_file تعریف کنیم. تابع هش md5 تمام محتوای فایل ما را به هش md5 تبدیل می کند. برای باز کردن یک فایل، ابتدا باید مسیر آن را داشته باشیم، بنابراین در اینجا از تابع دیگری در ماژول سیستم عامل به نام os.path.join() استفاده می کنیم. بنابراین می گوییم فایل را با استفاده از مسیر فایل در حالت خواندن باز کنید. با این کار فایل ما به هش md5 تبدیل می شود. برای بدست آوردن رشته هش از متد ()hexdigest استفاده می کنیم.
for root, folders, files in list_of_files:
for file in files:
file_path = Path(os.path.join(root, file))
Hash_file = hashlib.md5(open(
file_path,'rb').read()).hexdigest()
مرحله 5: برای شناسایی فایل های تکراری، یک دیکشنری خالی تعریف می کنیم. ما عناصری را به این فرهنگ لغت اضافه خواهیم کرد و کلید هر عنصر هش فایل و مقدار آن مسیر فایل خواهد بود. اگر هش فایل قبلاً به این فرهنگ لغت فایلهای منحصربهفرد اضافه شده باشد، به این معنی است که ما یک فایل تکراری پیدا کردهایم و باید آن فایل را حذف کنیم، بنابراین به سادگی آن فایل را با استفاده از تابع os.remove() حذف میکنیم . اگر آن را وجود ندارد، ما قصد داریم آن را به آن فرهنگ لغت اضافه کنیم.
unique_files = dict()
if Hash_file not in unique_files:
unique_files[Hash_file] = file_path
else:
os.remove(file_path)
print(f"{file_path} has been deleted")
در زیر اجرای کامل آن آمده است:
from tkinter.filedialog import askdirectory
# Importing required libraries.
from tkinter import Tk
import os
import hashlib
from pathlib import Path
# We don't want the GUI window of
# tkinter to be appearing on our screen
Tk().withdraw()
# Dialog box for selecting a folder.
file_path = askdirectory(title="Select a folder")
# Listing out all the files
# inside our root folder.
list_of_files = os.walk(file_path)
# In order to detect the duplicate
# files we are going to define an empty dictionary.
unique_files = dict()
for root, folders, files in list_of_files:
# Running a for loop on all the files
for file in files:
# Finding complete file path
file_path = Path(os.path.join(root, file))
# Converting all the content of
# our file into md5 hash.
Hash_file = hashlib.md5(open(file_path, 'rb').read()).hexdigest()
# If file hash has already #
# been added we'll simply delete that file
if Hash_file not in unique_files:
unique_files[Hash_file] = file_path
else:
os.remove(file_path)
print(f"{file_path} has been deleted")
ممنون از این مقاله کاربردی