在 Python 中对比两个文本文件,主要是检查它们的内容是否匹配或存在差异。这个过程能帮助我们识别文件是否完全相同,或者它们之间是否存在任何变动。无论是日志分析、数据校验还是代码审查,这都是我们经常遇到的基础需求。
> 点击下载本文中使用的文本文件
虽然我们有一些简单的方法来处理这个问题,但在 2026 年的今天,随着系统规模的扩大和 AI 辅助开发的普及,我们需要从更深入、更工程化的角度来审视这个问题。在这篇文章中,我们将不仅介绍基础方法,还会分享我们在企业级项目中的实战经验和避坑指南。
使用基于哈希的对比方法
这种方法会计算每个文件的 加密哈希值 (SHA-256),然后对比生成的哈希结果。如果哈希值相同,说明文件完全一致;如果不同,说明文件有差异。这种方法速度很快,即使处理大文件也能高效运行,但它无法告诉你具体的差异位置。
基础实现
import hashlib
def file_hash(path):
hasher = hashlib.sha256()
with open(path, ‘rb‘) as file:
# 使用生成器表达式分块读取,避免内存溢出
for chunk in iter(lambda: file.read(4096), b""):
hasher.update(chunk)
return hasher.hexdigest()
# 计算哈希值
hash1 = file_hash(r"C:\Users\GFG0578\New folder\intro.txt")
hash2 = file_hash(r"C:\Users\GFG0578\New folder\intro (1).txt")
print(f"File 1 Hash: {hash1}")
print(f"File 2 Hash: {hash2}")
print("Files are identical." if hash1 == hash2 else "Files differ.")
工程化演进:并行计算与性能优化
在我们最近的一个云原生数据处理项目中,我们需要对比数百 GB 的日志文件。单线程的哈希计算成为了瓶颈。为了解决这个问题,我们利用现代多核 CPU 的优势,引入了并行处理策略。
让我们思考一下这个场景: 当文件特别大时,I/O 操作和 CPU 计算必须重叠进行才能最大化效率。以下是我们在生产环境中使用的优化版本:
import hashlib
import os
from concurrent.futures import ThreadPoolExecutor
def hash_chunk(chunk):
"""辅助函数:计算单个块的哈希值"""
hasher = hashlib.sha256()
hasher.update(chunk)
return hasher.digest()
def parallel_file_hash(path, chunk_size=1024*1024*4): # 4MB chunks
"""利用多线程并行计算文件哈希(适用于超大文件)"""
# 预先读取所有块(注意:对于极端巨大的文件,仍需控制内存)
chunks = []
with open(path, ‘rb‘) as file:
while True:
chunk = file.read(chunk_size)
if not chunk:
break
chunks.append(chunk)
# 并行计算各块哈希
with ThreadPoolExecutor() as executor:
chunk_hashes = list(executor.map(hash_chunk, chunks))
# 合并结果
final_hash = hashlib.sha256()
for h in chunk_hashes:
final_hash.update(h)
return final_hash.hexdigest()
# 实战应用
hash1 = parallel_file_hash("large_log_a.txt")
hash2 = parallel_file_hash("large_log_b.txt")
避坑指南: 你可能会遇到这样的情况——在 Windows 和 Linux 系统之间迁移文件时,即使内容相同,哈希值却不同。这通常是因为换行符(CRLF vs LF)的差异。在处理跨平台文本对比时,我们通常建议先统一化换行符,或者使用 difflib 进行忽略空白字符的对比。
逐行流式对比
这种方法会逐行读取两个文件并对比对应的行。它能精确显示哪些行存在差异,而且因为不需要一次性将整个文件加载到内存中,所以非常节省内存。这对于识别文件之间具体的差异非常有用。
Python
with open(r"C:\Users\GFG0578\New folder\intro.txt", ‘r‘) as f1, open(r"C:\Users\GFG0578\New folder\intro (1).txt", ‘r‘) as f2:
line_num = 0
for line1, line2 in zip(f1, f2):
line_num += 1
if line1 != line2:
print(f"Line {line_num}:")
print(f"\tFile 1: {line1.strip()}")
print(f"\tFile 2: {line2.strip()}")
INLINECODEc3348cbczipINLINECODE6f04b5a1
使用 Readlines()
readlines() 会将两个文件的全部内容作为行列表读取到内存中,然后逐行进行对比。它能清楚地显示哪些行是相同的,哪些是不同的。然而,这会占用较多内存,可能不适合处理非常大的文件。
Python
f1 = open( r"C:\Users\GFG0578\New folder\intro.txt")
f2 = open(r"C:\Users\GFG0578\New folder\intro (1).txt")
f1_data = f1.readlines()
f2_data = f2.readlines()
i = 0
for line1, line2 in zip(f1_data, f2_data):
i += 1
if line1 == line2:
print(f"Line {i}: IDENTICAL")
else:
print(f"Line {i}:")
print(f"\tFile 1: {line1.strip()}")
print(f"\tFile 2: {line2.strip()}")
f1.close()
f2.close()
INLINECODEf3a1efaeforINLINECODEba6947a0difflibINLINECODE3e379aebencoding=‘utf-8‘INLINECODE13cf5616errors=‘ignore‘INLINECODE3a22b282‘replace‘INLINECODE6bb29a8cmmapINLINECODEfb88a4ccdifflibINLINECODEacee7474pandas` 用于结构化数据),拥抱 AI 辅助开发(利用 Cursor/Copilot 快速生成样板代码并发现边界情况),以及构建健壮的工程化系统(处理编码、内存和并发)。希望这些进阶技巧能帮助你在下一个项目中写出更优雅的代码。