3. 查找重复文件

查找重复文件 学习卡片

任务说明

在指定目录(含子目录)中,通过计算文件内容的 SHA-256 哈希值,找出内容完全相同的重复文件,并将重复组及其文件路径列表输出。本案例不处理硬链接、符号链接或空文件(空文件哈希相同但无实际意义,默认跳过)。

实现思路

使用 os.walk 递归遍历目录,对每个文件按块读取(避免大文件占用过多内存)计算 SHA-256 哈希。以哈希值为键、文件路径列表为值构建字典,最后筛选出长度大于 1 的列表即为重复文件组。输出时按重复组展示,每组内文件按路径排序。

代码实现

import os
import hashlib
from collections import defaultdict

def compute_sha256(file_path, chunk_size=8192):
    """计算文件的 SHA-256 哈希值"""
    sha256 = hashlib.sha256()
    with open(file_path, 'rb') as f:
        while True:
            chunk = f.read(chunk_size)
            if not chunk:
                break
            sha256.update(chunk)
    return sha256.hexdigest()

def find_duplicate_files(root_dir):
    """
    遍历 root_dir(含子目录),返回重复文件组列表。
    每组为一个列表,包含至少两个内容相同的文件路径。
    """
    hash_map = defaultdict(list)

    for dirpath, _, filenames in os.walk(root_dir):
        for filename in filenames:
            file_path = os.path.join(dirpath, filename)
            try:
                # 跳过空文件(大小为0)
                if os.path.getsize(file_path) == 0:
                    continue
                file_hash = compute_sha256(file_path)
                hash_map[file_hash].append(file_path)
            except (OSError, PermissionError):
                # 跳过无法访问的文件
                continue

    # 只保留重复组,并按组内路径排序
    duplicates = [paths for paths in hash_map.values() if len(paths) > 1]
    for group in duplicates:
        group.sort()
    return duplicates

if __name__ == "__main__":
    import sys
    if len(sys.argv) != 2:
        print("用法: python find_duplicates.py <目标目录>")
        sys.exit(1)

    target_dir = sys.argv[1]
    if not os.path.isdir(target_dir):
        print(f"错误: '{target_dir}' 不是有效目录")
        sys.exit(1)

    result = find_duplicate_files(target_dir)
    if not result:
        print("未发现重复文件。")
    else:
        print(f"发现 {len(result)} 组重复文件:\n")
        for idx, group in enumerate(result, 1):
            print(f"第 {idx} 组({len(group)} 个文件):")
            for path in group:
                print(f"  {path}")
            print()

运行与验证

运行方式:将代码保存为 find_duplicates.py,在命令行执行:

python find_duplicates.py /path/to/your/directory

验证方法:准备一个测试目录,手动复制两个相同内容的文件到不同子目录,再放一个内容不同的文件。运行脚本后,观察输出是否将相同内容的文件归为一组,且不同内容的文件未被列出。

判定标准:脚本输出的每组文件路径均对应内容完全相同的文件;所有重复文件均被找出,无遗漏;非重复文件不出现;无法访问的文件不影响程序运行。

重复文件检测流程 os.walk 遍历 递归读取所有文件 分块计算 SHA-256 每块 8KB,避免大文件占内存 哈希 → 路径列表 defaultdict(list) 存储 筛选重复组 路径数 > 1 的哈希组 输出重复组 每组显示文件路径列表 示例数据结构 hash_map = { "a1b2...c3": ["dir1/a.txt", "dir2/b.txt"], "d4e5...f6": ["dir1/unique.txt"], "g7h8...i9": ["dir3/x.doc", "dir4/y.doc", "dir5/z.doc"] } 筛选后:第1组(2个文件)、第3组(3个文件) 跳过:空文件、 无权限文件