В этой статье мы собираемся использовать концепцию, называемую хешированием, для идентификации уникальных файлов и удаления повторяющихся файлов с помощью Python.
Требуемые модули:
- tkinter: нам нужно дать нам возможность выбрать папку, в которой мы хотим выполнить этот процесс очистки, поэтому каждый раз, когда мы запускаем код, мы должны получать диалоговое окно файла для выбора папки, и мы собираемся использовать библиотеку Tkinter. В этой библиотеке у нас есть метод «askdirectory», который можно использовать, чтобы попросить пользователя выбрать каталог. Чтобы установить эту библиотеку, введите следующую команду в IDE/терминале.
pip install tk
- hashlib: чтобы использовать хеш-функцию md5, нам нужна библиотека hashlib. Чтобы установить эту библиотеку, введите следующую команду в IDE/терминале.
pip install hashlib
- os: этот модуль помогает нам удалять дубликаты файлов, предоставляя функции для извлечения содержимого файлов, удаления файлов и т. д. Чтобы установить эту библиотеку, введите следующую команду в IDE/терминал. Модуль os является частью стандартной библиотеки Python.
Подход:
- Мы попросим пользователя выбрать папку, и мы будем искать в этом зонтичном каталоге все повторяющиеся и избыточные файлы.
- Мы возьмем содержимое каждого файла и пропустим его через хеш-функцию, которая сгенерирует уникальную строку, соответствующую уникальному файлу.
- Хэш-строка будет иметь фиксированный размер, и размер будет зависеть от типа используемой хэш-функции. У нас есть много хеш-функций, таких как md5, SHA1 или SHA 256 и многие другие. В этой статье мы будем использовать хэш md5, и он всегда будет создавать хэш-значение длиной 32 символа, независимо от размера файла и типа файла.
- Чтобы обнаружить дубликаты файлов, а затем удалить эти файлы, мы будем поддерживать словарь Python.
- Мы собираемся передать хеш-строку каждого файла внутри каждой подпапки корневого каталога в качестве ключей словаря и путей к файлам в качестве значений словаря.
- Каждый раз при вставке новой файловой записи мы будем проверять, не появляются ли в нашем словаре повторяющиеся записи. Если мы найдем какой-либо дубликат файла, мы возьмем путь к файлу и удалим этот файл.
Поэтапная реализация
Шаг 1: Импортируйте библиотеки Tkinter, os, hashlib и pathlib.
Python 3
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») эта строка кода открывает диалоговое окно на экране, через которое мы можем выбрать папку.
Python 3
Tk().withdraw()
file_path
=
askdirectory(title
=
"Select a folder"
)
Шаг 3: Далее нам нужно перечислить все файлы в нашей корневой папке. Для этого нам нужен модуль ОС, os.walk() принимает путь к нашей корневой папке в качестве аргумента, проходит через каждый подкаталог данной ему папки и выводит список всех файлов. Эта функция возвращает список кортежей с тремя элементами. Первый элемент — это путь к этой папке, второй элемент — все подпапки внутри этой папки, а третий элемент — список всех файлов внутри этой папки.
Python 3
list_of_files
=
os.walk(file_path)
Шаг 4: Наша конечная цель — перечислить все файлы в каждом подкаталоге и в главном каталоге, поэтому мы запускаем цикл for для всех файлов. Нам нужно открыть каждый файл и преобразовать его в хеш-строку, для этого мы определим переменную с именем hash_file. Хэш-функция md5 преобразует все содержимое нашего файла в хэш md5. Чтобы открыть файл, нам нужно сначала указать путь к нему, поэтому здесь мы используем другую функцию в модуле os, которая называется os.path.join(). Итак, мы скажем открыть файл, используя путь к файлу в режиме чтения. Это преобразует наш файл в хэш md5. Чтобы получить хеш-строку, мы будем использовать метод hexdigest().
Python 3
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(). Если его там нет, мы добавим его в этот словарь.
Python3
unique_files
=
dict
()
if
Hash_file
not
in
unique_files:
unique_files[Hash_file]
=
file_path
else
:
os.remove(file_path)
(f
"{file_path} has been deleted"
)
Ниже приведена полная реализация:
Python3
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)
(f
"{file_path} has been deleted"
)