📜  使用Python删除重复文件

📅  最后修改于: 2022-05-13 01:54:32.774000             🧑  作者: Mango

使用Python删除重复文件

在本文中,我们将使用一个称为哈希的概念来识别唯一文件并使用Python删除重复文件。

所需模块:

  • tkinter: 我们需要为我们提供一种方法来选择我们想要在其中执行此清理过程的文件夹,因此每次运行代码时,我们应该得到一个文件对话框来选择一个文件夹,并且我们将使用 Tkinter 库。在这个库中,我们有一个名为“askdirectory”的方法,可以用来让用户选择一个目录。要安装此库,请在 IDE/终端中键入以下命令。
pip install tk
  • hashlib:为了使用 md5 哈希函数,我们需要 hashlib 库。要安装此库,请在 IDE/终端中键入以下命令。
pip install hashlib
  • 操作系统: 该模块通过提供获取文件内容和删除文件等功能帮助我们删除重复文件。要安装此库,请在 IDE/终端中键入以下命令。 os 模块是Python中标准库的一部分。

方法:

  • 我们将要求用户选择一个文件夹,我们将在这个总目录下搜索所有重复和冗余文件。
  • 我们将获取每个文件的内容并将其传递给一个哈希函数,该函数将生成一个与唯一文件相对应的唯一字符串。
  • 哈希字符串将是固定大小,大小取决于我们使用的哈希函数的类型。我们有许多散列函数,例如 md5、SHA1 或 SHA 256 等等。在本文中,我们将使用 md5 哈希,无论文件大小和文件类型如何,它总是会产生 32 个字符长的哈希值。
  • 为了检测重复文件然后删除这些文件,我们将维护一个Python字典。
  • 我们将传递根目录的每个子文件夹中每个文件的哈希字符串作为字典的键和文件路径作为字典的值。
  • 每次插入新文件记录时,我们都会检查字典中是否有任何重复的条目。如果我们发现任何重复文件,我们将获取文件的路径并删除该文件。

逐步实施

第 1 步:导入 Tkinter、os、hashlib 和 pathlib 库。

Python3
from tkinter.filedialog import askdirectory
from tkinter import Tk
import os
import hashlib
from pathlib import Path


Python3
Tk().withdraw()
file_path = askdirectory(title="Select a folder")


Python3
list_of_files = os.walk(file_path)


Python3
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()


Python3
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")


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)
            print(f"{file_path} has been deleted")


第 2 步:我们使用 tk.withdraw 因为我们不希望 tkinter 的 GUI 窗口出现在我们的屏幕上,我们只希望文件对话框用于选择文件夹。 askdirectory(title="Select a folder") 这行代码在屏幕上弹出一个对话框,我们可以通过它选择一个文件夹。

Python3

Tk().withdraw()
file_path = askdirectory(title="Select a folder")

第 3 步:接下来,我们需要列出根文件夹中的所有文件。为此,我们需要 OS 模块,os.walk() 将根文件夹的路径作为参数,它将遍历给它的文件夹的每个子目录,并列出所有文件。这个函数返回一个包含三个元素的元组列表。第一个元素是该文件夹的路径,第二个元素是该文件夹内的所有子文件夹,第三个元素是该文件夹内所有文件的列表。

Python3

list_of_files = os.walk(file_path)

第 4 步:我们的最终目标是列出每个子目录和主目录中的所有文件,这就是我们对所有文件运行 for 循环的原因。我们需要打开每个文件并将其转换为哈希字符串,为此我们将定义一个名为 hash_file 的变量。 md5 哈希函数会将我们文件的所有内容转换为 md5 哈希。为了打开一个文件,我们首先需要它的路径,所以在这里我们使用 os 模块中的另一个函数,称为 os.path.join()。所以我们会说在读取模式下使用文件路径打开文件。这会将我们的文件转换为 md5 哈希。为了获得哈希字符串,我们将使用 hexdigest() 方法。

Python3

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)
    print(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)
            print(f"{file_path} has been deleted")

输出: