使用 Python 查找重复文件

pythonserver side programmingprogramming

复制文档是常有的事,因为我们在 PC 上收集信息时,复制文档会占用硬盘上的额外空间,因此,手动查找和删除重复文件可能非常耗时且令人厌烦;幸运的是,我们可以使用 Python 自动执行此过程,因此在本课中,我们将了解如何使用简短的脚本执行此操作。

设置

在本教程中,我们将使用 Python 中的内置 oshashlib 模块,因此无需安装其他软件包。

import os
import hashlib

算法

  • 编写一个名为 hashfile() 的函数,该函数利用 SHA-1 计算生成具有明确哈希值的文档,该文档接受文件名作为信息并返回哈希值。

  • 定义方法 find_duplicates(),允许在特定目录;它为每个参数(例如目录名)生成一系列包含重复文件的文件位置的列表。

  • 在跟踪 copies() 方法中,将每个目录文件的哈希值存储在一个目录引用中,并使用 hashfile() 方法迭代地计算哈希值作为每个目录文件的引用。

  • 如果哈希值已经在目录引用中,则将文件路径添加到重复文件列表中。如果不是,则目录将包含哈希值和文件位置。

  • 由于这些内部文件实际上不包含重复文件路径,因此请将它们排除在外。

示例

import os
import hashlib
def hashfile(filename):
   with open(filename, 'rb') as f:
      hasher = hashlib.sha1()
      while True:
         data = f.read(1024)
         if not data:
            break
         hasher.update(data)
      return hasher.hexdigest()

此代码在 Python hashlib 模块的帮助下创建了方法 hashfile(),上述方法返回文件的 SHA-1 哈希值,并将文件名作为其输入。当从文件中一次读取 1024 个字节时,该函数会更改每个块的哈希值。在阅读完整记录后,该函数将哈希值的 hexdigest 以字符串形式返回。

def find_duplicates(dirname):
   files = os.listdir(dirname)
   if len(files) < 2:
      return
   hashes = {}
   for filename in files:
      path = os.path.join(dirname, filename)
      if not os.path.isfile(path):
         continue
      file_hash = hashfile(path)
      if file_hash not in hashes:
         hashes[file_hash] = path
      else:
         print(f'Duplicate found: {path} and {hashes[file_hash]}')

此代码中的方法 find duplicates() 定义了一个列表列表,其中包含重复文件的文件路径,并接受目录名称作为输入。该函数创建一个空的重复列表和一个空的字典文件,分别包含重复文件的路径和目录中每个文件的哈希值。使用 os.listdir() 方法,代码遍历目录中的每个文件,并使用 os.path.isfile() 函数确定它是否是文件。

该函数使用先前定义的 hashfile() 函数为每个文件创建一个哈希值,并检查文件的字典中是否已经存在该哈希值。如果哈希值已经存在,则该函数将当前文件路径和具有相同哈希值的前一个文件的路径添加到重复列表中。该函数最终返回的是所有发现的重复项的列表。

最后调用该方法运行整个脚本 −

if __name__ == '__main__':
   show_duplicates('.')

解释

So the whole code can be written as −

import os
import hashlib
def hashfile(filename):
   with open(filename, 'rb') as f:
      hasher = hashlib.sha1()
      while True:
         data = f.read(1024)
         if not data:
            break
         hasher.update(data)
      return hasher.hexdigest()
 
def find_duplicates(dirname):
   files = os.listdir(dirname)
   if len(files) < 2:
      return
   hashes = {}
   for filename in files:
      path = os.path.join(dirname, filename)
      if not os.path.isfile(path):
         continue
      file_hash = hashfile(path)
      if file_hash not in hashes:
         hashes[file_hash] = path
      else:
         print(f'Duplicate found: {path} and {hashes[file_hash]}')
            
if __name__ == '__main__':
   show_duplicates('.')

输出

[您可以将多个文件复制粘贴到运行脚本的目录中以获得所需的输出]

Duplicate found: .\DSA-guide-2023.pdf and .\DSA-guide-2023 - Copy.pdf
  • 我们首先引入 os 模块,它提供了一种与工作框架协作的方法。

  • 然后定义 find_duplicates 函数,该函数返回在给定目录中找到的所有重复文件的列表,并将目录作为其输入。

  • 用于存储每个文件的哈希值的字典是 hash_dict 变量。

  • 发现重复的任何文件的路径都将存储在 duplicates 中的列表中变量。

  • 然后,我们使用 os.walk 函数遍历目录及其子目录。

  • 对于注册表中的每个文档,我们使用 hash_file 函数来计算其哈希值。

  • 然后,我们检查 hash_dict 字典,看看哈希值是否已经存在。如果存在,则将当前文件的路径和之前具有相同哈希值的文件的路径添加到重复列表中。如果哈希值和文件路径尚不存在,则将其添加到 hash_dict 字典中。

  • 发回重复项列表,其中包括找到的所有重复文件,并将其打印出来。

结论

即使可能需要一些开支,识别文件副本对于保持我们框架的秩序和整洁也是必不可少的。在这篇文章中,我们展示了如何利用 Python 的 os 模块和 hashlib 模块在注册表中查找文档的重复副本。os 模块简化了操作系统通信,而 hashlib 模块允许我们访问文件的哈希值。通过合并这两个模块,我们能够构建"查找重复项"函数,该函数可以定位目录中的重复文件。


相关文章