【Python】基于文件内容的重复文件查找与管理
脚本功能
该脚本的主要功能是扫描指定目录及其子目录中的所有文件,通过计算文件的哈希值来识别重复文件,并提供多种删除选项。其工作流程大致分为以下几个步骤:
计算文件哈希值:通过哈希算法(默认为SHA-256)计算文件的唯一标识。
查找重复文件:扫描指定目录,找出文件内容相同(哈希值相同)的文件。
删除重复文件:用户可以选择保留一个文件并删除其余重复文件,或者删除所有重复文件,或者跳过删除操作。
代码实现:
import os
import hashlib
from collections import defaultdict
def calculate_file_hash(file_path, hash_algorithm=hashlib.sha256):
"""
计算文件的哈希值(默认使用 SHA256)。
参数:
- file_path (str): 文件的完整路径。
- hash_algorithm: 哈希算法,默认为 hashlib.sha256。
返回:
- str: 文件的哈希值(十六进制字符串)。
"""
hash_object = hash_algorithm() # 创建哈希对象
try:
with open(file_path, 'rb') as f: # 以二进制模式打开文件
while chunk := f.read(8192): # 按 8192 字节(8KB)分块读取文件
hash_object.update(chunk) # 更新哈希对象
return hash_object.hexdigest() # 返回哈希值(十六进制字符串)
except (IOError, OSError): # 捕获文件无法读取的异常
print(f"无法读取文件: {file_path},跳过...")
return None # 返回 None 以指示读取失败
def find_duplicate_files(directory):
"""
查找指定目录及其子目录中的所有重复文件(基于文件内容)。
参数:
- directory (str): 要检查的目录路径。
返回:
- dict: 以哈希值为键,文件路径列表为值的字典,仅包含重复文件。
"""
hashes = defaultdict(list) # 用于存储哈希值到文件路径的映射
for root, _, files in os.walk(directory): # 遍历目录树
for file in files:
file_path = os.path.join(root, file) # 获取完整文件路径
file_hash = calculate_file_hash(file_path) # 计算文件的哈希值
if file_hash: # 仅存储成功计算哈希的文件
hashes[file_hash].append(file_path)
# 过滤掉哈希值只对应一个文件的项,仅保留重复文件
return {hash_val: paths for hash_val, paths in hashes.items() if len(paths) > 1}
def delete_files(file_paths):
"""
删除用户选择的重复文件,并提供保留选项。
参数:
- file_paths (list): 具有相同内容的重复文件路径列表。
"""
if len(file_paths) < 2:
return # 如果列表中少于两个文件,则无需删除
print("\n发现重复文件:")
for i, path in enumerate(file_paths, start=1):
print(f"{i}. {path}")
# 让用户选择如何处理重复文件
choice = input("请选择操作:\n1. 保留一个文件并删除其他\n2. 删除所有重复文件\n3. 跳过\n输入编号: ")
if choice == '1': # 选择保留一个文件
keep_index = int(input("请输入要保留的文件编号: ")) - 1
if 0 <= keep_index < len(file_paths): # 确保输入编号有效
keep_path = file_paths.pop(keep_index) # 取出用户选择保留的文件路径
print(f"保留文件: {keep_path}")
for path in file_paths: # 删除其他文件
os.remove(path)
print(f"已删除: {path}")
else:
print("无效的选择,跳过删除操作。")
elif choice == '2': # 选择删除所有重复文件
for path in file_paths:
os.remove(path)
print(f"已删除: {path}")
else: # 选择跳过
print("跳过删除操作。")
def main():
"""
主函数:获取用户输入目录,查找并处理重复文件。
"""
directory = input("请输入要查找的目录路径: ").strip()
if not os.path.isdir(directory): # 检查输入路径是否为有效目录
print("无效的目录路径,请重新输入。")
return
print("\n正在扫描目录,查找重复文件...")
duplicates = find_duplicate_files(directory) # 查找重复文件
if not duplicates: # 如果未找到重复文件
print("未找到重复文件。")
return
# 遍历重复文件列表,逐组处理
for _, file_paths in duplicates.items():
delete_files(file_paths)
if __name__ == "__main__":
main() # 运行主函数
主要函数解释
calculate_file_hash(file_path, hash_algorithm)
此函数的目的是计算指定文件的哈希值。默认使用SHA-256算法,用户也可以传入其他哈希算法。文件会以二进制方式读取,并以8192字节(8KB)为单位分块读取,适合处理大文件。
参数:
file_path
:文件的路径。hash_algorithm
:哈希算法(默认为hashlib.sha256
)。
返回:返回计算出的文件哈希值(十六进制字符串),如果文件无法读取,返回
None
。
find_duplicate_files(directory)
此函数扫描指定目录(包括子目录)中的所有文件,计算文件的哈希值,并将相同哈希值的文件路径收集在一起。最后,返回的字典中,哈希值作为键,路径列表作为值,仅包含重复文件。
参数:
directory
:需要扫描的目录路径。
返回:一个字典,键为文件哈希值,值为相同内容文件的路径列表。
delete_files(file_paths)
此函数让用户选择如何处理重复文件。它会列出所有重复文件并提供三种操作选择:
保留一个文件,删除其他重复文件。
删除所有重复文件。
跳过删除操作。
参数:
file_paths
:包含重复文件路径的列表。
main()
主函数是整个脚本的入口,它会提示用户输入需要扫描的目录路径。程序会检查路径是否合法,然后调用find_duplicate_files
函数查找重复文件。如果发现重复文件,将会调用delete_files
函数让用户处理这些文件。
流程:
提示用户输入目录路径。
如果目录有效,则扫描并查找重复文件。
如果找到重复文件,调用
delete_files
处理。
代码工作原理
文件哈希计算:通过读取文件并计算哈希值,文件内容相同的文件会拥有相同的哈希值。这样,即使文件名不同,只要内容相同,也能被判定为重复文件。
扫描目录:通过
os.walk()
函数遍历指定目录及其子目录,计算每个文件的哈希值,将哈希值相同的文件归类。删除操作:根据用户选择,脚本提供不同的删除选项。用户可以保留一个文件并删除其他重复文件,或删除所有重复文件。
使用示例
输入目录路径:用户需要输入想要检查的目录路径。
显示重复文件:程序会列出所有发现的重复文件,并让用户选择如何处理这些文件。
选择操作:
如果用户选择保留一个文件,程序会删除其余重复文件。
如果选择删除所有重复文件,程序会删除所有具有相同内容的文件。
如果选择跳过,程序则不会删除任何文件。
示例:请输入要查找的目录路径: /path/to/your/directory 正在扫描目录,查找重复文件... 发现重复文件: 1. /path/to/your/directory/file1.txt 2. /path/to/your/directory/subdir/file1.txt 3. /path/to/your/directory/file2.txt 请选择操作: 1. 保留一个文件并删除其他 2. 删除所有重复文件 3. 跳过 输入编号: 1 请输入要保留的文件编号: 1 保留文件: /path/to/your/directory/file1.txt 已删除: /path/to/your/directory/subdir/file1.txt 已删除: /path/to/your/directory/file2.txt
输出说明:
程序首先扫描目录并发现了三个文件,其中两个文件内容相同(哈希值一致),一个文件为不同内容。
然后,程序显示重复文件列表,并提示用户选择操作。
用户选择保留第一个文件(
file1.txt
),并删除其余重复文件(subdir/file1.txt
和file2.txt
)。最终,程序输出哪些文件被保留,哪些文件被删除。
优点
高效处理:通过哈希算法比较文件内容,比直接比较文件大小或名称更为精准和高效。
灵活操作:用户可以根据需要选择不同的删除策略,避免误删重要文件。
适用大目录:支持遍历包含子目录的大型目录结构,适合处理大量文件。
总结
该脚本非常适合那些需要处理大量文件并寻找重复内容的场景。通过计算哈希值,它能够准确地识别出内容相同的文件,即使文件名不同,也能够识别出来。用户可以根据自己的需求灵活地选择删除策略,从而帮助清理磁盘空间并保持文件管理的整洁。
如果有进一步的需求,比如修改哈希算法或添加更复杂的删除逻辑,脚本也是可以进行扩展和定制的。
评论