在 Python 中比较文件内容,最直接和可靠的方法是逐行读取文件内容并进行比较,下面我将介绍几种常用的方法,从简单到复杂,并解释它们的优缺点。

逐行比较(推荐)
这是最常用、最灵活的方法,尤其适用于文本文件,它可以处理不同行尾符(\n vs \r\n)的问题,并且可以方便地输出差异所在的具体行号。
优点:
- 准确可靠,适用于各种文本文件。
- 可以定位到具体的差异行。
- 内存效率高,因为它不会一次性将整个文件读入内存。
缺点:
- 对于二进制文件(如图片、视频、
.exe),逐行比较没有意义。
代码示例:

def compare_files_line_by_line(file1_path, file2_path):
"""
逐行比较两个文本文件,并报告差异。
"""
try:
with open(file1_path, 'r', encoding='utf-8') as f1, open(file2_path, 'r', encoding='utf-8') as f2:
line_number = 0
differences_found = False
# 使用 zip 同时遍历两个文件的行
for line1, line2 in zip(f1, f2):
line_number += 1
if line1 != line2:
differences_found = True
print(f"差异在第 {line_number} 行:")
print(f" 文件1: {line1.rstrip()}")
print(f" 文件2: {line2.rstrip()}")
print("-" * 20)
# 检查文件长度是否不同
if not differences_found:
# 检查一个文件是否比另一个更长
# 使用 next() 来检查是否还有剩余行
try:
next(f1)
print(f"警告: 文件1 ('{file1_path}') 比文件2 ('{file2_path}') 长。")
differences_found = True
except StopIteration:
pass
try:
next(f2)
print(f"警告: 文件2 ('{file2_path}') 比文件1 ('{file1_path}') 长。")
differences_found = True
except StopIteration:
pass
if not differences_found:
print("两个文件内容完全相同。")
except FileNotFoundError as e:
print(f"错误: {e}")
except Exception as e:
print(f"发生未知错误: {e}")
# --- 使用示例 ---
# 创建两个用于测试的文件
with open("file1.txt", "w", encoding="utf-8") as f:
f.write("这是第一行,\n")
f.write("这是第二行,有差异,\n")
f.write("这是第三行,\n")
with open("file2.txt", "w", encoding="utf-8") as f:
f.write("这是第一行,\n")
f.write("这是文件二的第二行,\n") # 这一行不同
f.write("这是第三行,\n")
f.write("文件二多出的这一行,\n") # 文件2更长
print("--- 比较开始 ---")
compare_files_line_by_line("file1.txt", "file2.txt")
print("--- 比较结束 ---")
# 清理测试文件
import os
os.remove("file1.txt")
os.remove("file2.txt")
哈希比较(最快)
如果你只想知道两个文件是否完全相同,而不关心具体哪里不同,那么计算文件的哈希值是最快的方法,哈希值就像是文件的“数字指纹”,如果两个文件的哈希值相同,那么它们的内容也必然相同。
优点:
- 速度极快,尤其适合大文件。
- 代码非常简洁。
- 适用于文本和二进制文件。
缺点:
- 无法提供差异的具体位置或内容信息。
代码示例:
import hashlib
def get_file_hash(file_path, algorithm='sha256'):
"""
计算文件的哈希值。
"""
hasher = hashlib.new(algorithm)
try:
with open(file_path, 'rb') as f: # 必须以二进制模式('rb')读取
# 分块读取文件,避免内存问题
while chunk := f.read(8192): # 每次读取 8KB
hasher.update(chunk)
return hasher.hexdigest()
except FileNotFoundError:
print(f"错误: 文件 '{file_path}' 未找到。")
return None
def compare_files_by_hash(file1_path, file2_path):
"""
通过比较哈希值来判断两个文件是否相同。
"""
hash1 = get_file_hash(file1_path)
hash2 = get_file_hash(file2_path)
if hash1 is None or hash2 is None:
return # 错误已在 get_file_hash 中打印
if hash1 == hash2:
print(f"文件 '{file1_path}' 和 '{file2_path}' 内容完全相同。")
print(f"SHA256 哈希值: {hash1}")
else:
print(f"文件 '{file1_path}' 和 '{file2_path}' 内容不同。")
print(f"文件1的哈希: {hash1}")
print(f"文件2的哈希: {hash2}")
# --- 使用示例 ---
# 创建两个内容相同的文件
with open("same_file1.txt", "w", encoding="utf-8") as f:
f.write("Hello, World!")
with open("same_file2.txt", "w", encoding="utf-8") as f:
f.write("Hello, World!")
# 创建一个内容不同的文件
with open("different_file.txt", "w", encoding="utf-8") as f:
f.write("Hello, Python!")
print("\n--- 哈希比较开始 ---")
compare_files_by_hash("same_file1.txt", "same_file2.txt")
compare_files_by_hash("same_file1.txt", "different_file.txt")
print("--- 哈希比较结束 ---")
# 清理测试文件
import os
os.remove("same_file1.txt")
os.remove("same_file2.txt")
os.remove("different_file.txt")
使用 difflib 库(功能强大)
Python 标准库 difflib 提供了更高级的比较功能,可以生成类似 diff 命令的详细差异报告,这对于生成用户友好的比较结果非常有用。
优点:
- 功能非常强大,可以生成多种格式的差异报告。
- 可以处理增删改等多种差异情况。
- 是标准库的一部分,无需额外安装。
缺点:
- 对于非常大的文件,可能会消耗较多内存。
代码示例:
import difflib
def compare_files_with_difflib(file1_path, file2_path):
"""
使用 difflib 比较两个文件并生成差异报告。
"""
try:
with open(file1_path, 'r', encoding='utf-8') as f1, \
open(file2_path, 'r', encoding='utf-8') as f2:
f1_lines = f1.readlines()
f2_lines = f2.readlines()
# 使用 Differ 生成差异
differ = difflib.Differ()
diff = list(differ.compare(f1_lines, f2_lines))
# 打印差异
print(f"--- 文件差异报告: {file1_path} vs {file2_path} ---")
if not diff:
print("两个文件内容完全相同。")
else:
for line in diff:
# 只显示有差异的行
if line.startswith((' ', '- ', '+ ', '? ')):
print(line, end='') # end='' 因为每行已经包含了换行符
except FileNotFoundError as e:
print(f"错误: {e}")
except Exception as e:
print(f"发生未知错误: {e}")
# --- 使用示例 ---
# 创建两个用于测试的文件
with open("diff_file1.txt", "w", encoding="utf-8") as f:
f.write("苹果\n")
f.write("香蕉\n")
f.write("橙子\n")
with open("diff_file2.txt", "w", encoding="utf-8") as f:
f.write("苹果\n")
f.write("葡萄\n") # 修改
f.write("西瓜\n") # 新增
# f.write("橙子\n") # 删除
print("\n--- difflib 比较开始 ---")
compare_files_with_difflib("diff_file1.txt", "diff_file2.txt")
print("--- difflib 比较结束 ---")
# 清理测试文件
import os
os.remove("diff_file1.txt")
os.remove("diff_file2.txt")
总结与选择
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 逐行比较 | 需要知道具体差异的文本文件 | 灵活,可定位行号,内存高效 | 不适用于二进制文件 |
| 哈希比较 |
