如何通过 MD5 哈希算法找到目录中的重复文件?
2、解决方案
方法一:使用哈希表
使用哈希表可以轻松地查找重复文件。以下是步骤:
- 使用
collections.defaultdict创建一个哈希表,其中键是文件哈希值,值是文件名列表。 - 遍历目录中的每个文件,并计算其哈希值。
- 将哈希值和文件名添加到哈希表中。如果哈希值已经存在,则将文件名添加到文件名列表中。
- 遍历哈希表,并查找哈希值列表长度大于 1 的键。这些键对应于重复文件。
方法二:使用大小预过滤
该方法首先按相同大小对文件进行分组,然后对每个组中的文件计算 MD5 哈希值。这样可以减少 MD5 计算次数,提高效率。
以下是步骤:
- 遍历目录中的每个文件,并根据文件大小对文件进行分组。
- 对每个组中的文件计算 MD5 哈希值。
- 将哈希值和文件名添加到哈希表中。如果哈希值已经存在,则将文件名添加到文件名列表中。
- 遍历哈希表,并查找哈希值列表长度大于 1 的键。这些键对应于重复文件。
代码示例(方法一):
from collections import defaultdict
import hashlib
import os
def find_duplicate_files(directory):
# 创建一个哈希表,其中键是文件哈希值,值是文件名列表
hash_table = defaultdict(list)
# 遍历目录中的每个文件
for root, dirs, files in os.walk(directory):
for file in files:
# 计算文件的 MD5 哈希值
file_path = os.path.join(root, file)
hash_value = hashlib.md5(open(file_path, 'rb').read()).hexdigest()
# 将哈希值和文件名添加到哈希表中
hash_table[hash_value].append(file_path)
# 遍历哈希表,并查找哈希值列表长度大于 1 的键
duplicate_files = []
for hash_value, file_paths in hash_table.items():
if len(file_paths) > 1:
duplicate_files.append(file_paths)
return duplicate_files
# 打印重复文件
for duplicate_file in find_duplicate_files('/Users/bubble/Desktop/aF'):
print('Duplicate files:')
for file_path in duplicate_file:
print(file_path)
代码示例(方法二):
from collections import defaultdict
import hashlib
import os
def find_duplicate_files(directory):
# 创建一个哈希表,其中键是文件大小,值是文件名列表
size_map = defaultdict(list)
# 遍历目录中的每个文件
for root, dirs, files in os.walk(directory):
for file in files:
# 计算文件的大小
file_path = os.path.join(root, file)
file_size = os.path.getsize(file_path)
# 将文件大小和文件名添加到哈希表中
size_map[file_size].append(file_path)
# 遍历哈希表,并查找哈希值列表长度大于 1 的键
duplicate_files = []
for file_size, file_paths in size_map.items():
if len(file_paths) > 1:
# 计算文件哈希值
hash_table = defaultdict(list)
for file_path in file_paths:
hash_value = hashlib.md5(open(file_path, 'rb').read()).hexdigest()
hash_table[hash_value].append(file_path)
# 遍历哈希表,并查找哈希值列表长度大于 1 的键
for hash_value, file_paths in hash_table.items():
if len(file_paths) > 1:
duplicate_files.append(file_paths)
return duplicate_files
# 打印重复文件
for duplicate_file in find_duplicate_files('/Users/bubble/Desktop/aF'):
print('Duplicate files:')
for file_path in duplicate_file:
print(file_path)