以下是一个用Python实现对比两个文件夹文件差异的代码示例。这个脚本能够递归检查两个文件夹,找出仅存在于其中一个文件夹的文件、内容不同的文件以及同名但类型不同的项目(如一个是文件另一个是文件夹)。
这个代码实现了以下功能:1. 递归比较两个文件夹及其子文件夹中的所有内容
2. 识别四种类型的差异:- 仅存在于第一个文件夹中的文件/文件夹- 仅存在于第二个文件夹中的文件/文件夹- 名称相同但内容不同的文件- 名称相同但类型不同的项目(一个是文件,一个是文件夹)3. 提供两种结果输出方式:- 控制台打印,方便快速查看- 保存为文本文件(folder_comparison_report.txt),便于存档或分享4. 采用两级比较机制提高效率:- 先比较文件大小,快速排除不同的文件- 对大小相同的文件再计算MD5哈希值进行精确比较使用方法很简单,只需修改代码中的folder1
和folder2
变量为你要比较的两个文件夹路径,然后运行脚本即可。脚本会自动处理子文件夹,并生成详细的差异报告。
如果需要比较非常大的文件夹,可能需要一些时间,因为要计算文件的哈希值。对于一般大小的文件夹,这个脚本应该能在合理时间内完成比较。
import os
import filecmp
import hashlib
from datetime import datetimedef get_file_hash(file_path, block_size=65536):"""计算文件的MD5哈希值,用于精确比较内容"""hasher = hashlib.md5()with open(file_path, 'rb') as f:buf = f.read(block_size)while buf:hasher.update(buf)buf = f.read(block_size)return hasher.hexdigest()def compare_files(file1, file2):"""比较两个文件是否内容相同"""# 先比较大小,快速排除不同的文件if os.path.getsize(file1) != os.path.getsize(file2):return False# 大小相同再比较哈希值return get_file_hash(file1) == get_file_hash(file2)def compare_folders(folder1, folder2, result=None, relative_path=""):"""递归比较两个文件夹的差异"""if result is None:result = {'only_in_folder1': [], # 仅在第一个文件夹中存在'only_in_folder2': [], # 仅在第二个文件夹中存在'different_content': [], # 内容不同的文件'different_type': [] # 类型不同(一个是文件一个是文件夹)}# 获取两个文件夹中的所有项目items1 = set(os.listdir(folder1)) if os.path.exists(folder1) else set()items2 = set(os.listdir(folder2)) if os.path.exists(folder2) else set()# 检查仅存在于第一个文件夹中的项目for item in items1 - items2:item_path = os.path.join(relative_path, item)result['only_in_folder1'].append(item_path)# 检查仅存在于第二个文件夹中的项目for item in items2 - items1:item_path = os.path.join(relative_path, item)result['only_in_folder2'].append(item_path)# 检查两个文件夹中都存在的项目for item in items1 & items2:path1 = os.path.join(folder1, item)path2 = os.path.join(folder2, item)item_path = os.path.join(relative_path, item)is_file1 = os.path.isfile(path1)is_file2 = os.path.isfile(path2)# 一个是文件,一个是文件夹if is_file1 != is_file2:result['different_type'].append(item_path)continue# 都是文件夹,递归比较if not is_file1:compare_folders(path1, path2, result, item_path)# 都是文件,比较内容else:if not compare_files(path1, path2):result['different_content'].append(item_path)return resultdef print_results(result, folder1, folder2):"""打印比较结果"""print(f"文件夹比较结果:")print(f"文件夹1: {os.path.abspath(folder1)}")print(f"文件夹2: {os.path.abspath(folder2)}")print(f"比较时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")print("=" * 70)# 打印仅在第一个文件夹中存在的项目if result['only_in_folder1']:print(f"\n仅在 {folder1} 中存在的项目:")for item in sorted(result['only_in_folder1']):print(f" - {item}")# 打印仅在第二个文件夹中存在的项目if result['only_in_folder2']:print(f"\n仅在 {folder2} 中存在的项目:")for item in sorted(result['only_in_folder2']):print(f" - {item}")# 打印内容不同的文件if result['different_content']:print(f"\n内容不同的文件:")for item in sorted(result['different_content']):print(f" - {item}")# 打印类型不同的项目if result['different_type']:print(f"\n类型不同的项目 (一个是文件,一个是文件夹):")for item in sorted(result['different_type']):print(f" - {item}")# 如果没有差异if not any(result.values()):print("\n两个文件夹内容完全相同")def save_results_to_file(result, folder1, folder2, output_file="folder_comparison_report.txt"):"""将比较结果保存到文件"""with open(output_file, 'w', encoding='utf-8') as f:f.write(f"文件夹比较结果:\n")f.write(f"文件夹1: {os.path.abspath(folder1)}\n")f.write(f"文件夹2: {os.path.abspath(folder2)}\n")f.write(f"比较时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")f.write("=" * 70 + "\n")if result['only_in_folder1']:f.write(f"\n仅在 {folder1} 中存在的项目:\n")for item in sorted(result['only_in_folder1']):f.write(f" - {item}\n")if result['only_in_folder2']:f.write(f"\n仅在 {folder2} 中存在的项目:\n")for item in sorted(result['only_in_folder2']):f.write(f" - {item}\n")if result['different_content']:f.write(f"\n内容不同的文件:\n")for item in sorted(result['different_content']):f.write(f" - {item}\n")if result['different_type']:f.write(f"\n类型不同的项目 (一个是文件,一个是文件夹):\n")for item in sorted(result['different_type']):f.write(f" - {item}\n")if not any(result.values()):f.write("\n两个文件夹内容完全相同\n")print(f"\n结果已保存到: {os.path.abspath(output_file)}")def main():# 示例文件夹路径,可以根据需要修改folder1 = "test_folder1"folder2 = "test_folder2"# 检查文件夹是否存在if not os.path.exists(folder1):print(f"错误: 文件夹 '{folder1}' 不存在")returnif not os.path.exists(folder2):print(f"错误: 文件夹 '{folder2}' 不存在")return# 比较文件夹print(f"正在比较文件夹...")result = compare_folders(folder1, folder2)# 显示结果print_results(result, folder1, folder2)# 保存结果到文件save_results_to_file(result, folder1, folder2)if __name__ == "__main__":main()