Python 查找重复文件
在我们的计算机上收集信息时,复制文件会消耗硬盘上的额外空间,这是一种常见的情况,因此,手动查找和删除重复文件可能是耗时且繁琐的。幸运的是,我们可以使用Python自动化此过程,因此在本课程中我们将学习如何使用一个简短的脚本来实现这个目标。
设置
在本教程中,我们将使用Python中的内置模块 os 和 hashlib ,因此不需要安装其他额外的包。
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('.')
解释
所以整个代码可以写成−
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 字典,看看哈希值是否已经存在。如果存在,则将当前文件的路径和具有相同哈希值的前一个文件的路径添加到 duplicates 列表中。如果哈希值不存在,则将哈希值和文件路径添加到 hash_dict 字典中。
-
返回包含所有找到的重复文件的 duplicates 列表,并打印出来。
结论
即使可能需要一些开销,识别文件的副本对于维护我们的系统的秩序和整洁是必不可少的。在本文中,我们展示了如何使用 Python 的 os 模块和 hashlib 模块来查找目录中的重复文件。os 模块简化了与操作系统的通信,而 hashlib 模块允许我们访问文件的哈希值。通过合并这两个模块,我们能够构建出可以在目录中查找重复文件的 “find duplicates” 函数。