本文目录导读:

实现文件差异对比功能,通常使用逐行比较的算法(类似于 Unix 的 diff 命令),最经典且高效的算法是 最长公共子序列。
以下我会用 Python 和 JavaScript 两种最常用的脚本语言,为你提供完整的实现方案,并包含详细的注释。
核心思想
- 读取:将两个文件分别读入内存,按行拆分成列表。
- 比对:使用 LCS 或 Myers 差异算法找出两个列表中的相同行和不同行。
- 输出:标记出新增、删除、修改的行。
Python 实现(推荐,功能强大)
Python 有非常成熟的内置库 difflib,几乎实现了 diff 命令的全部功能。
简易版:使用 difflib.unified_diff(生成统一格式 diff)
import difflib
import sys
def compare_files_unified(file1_path, file2_path):
"""
读取两个文件,输出 unified 格式的差异(类似 git diff)
"""
try:
with open(file1_path, 'r', encoding='utf-8') as f1, \
open(file2_path, 'r', encoding='utf-8') as f2:
lines1 = f1.readlines()
lines2 = f2.readlines()
# 生成差异生成器
diff = difflib.unified_diff(
lines1,
lines2,
fromfile=file1_path, # 左侧文件名
tofile=file2_path, # 右侧文件名
lineterm='' # 避免多余换行
)
# 逐行输出结果
for line in diff:
print(line)
except FileNotFoundError as e:
print(f"文件未找到: {e}", file=sys.stderr)
except Exception as e:
print(f"读取文件出错: {e}", file=sys.stderr)
# 示例用法
if __name__ == "__main__":
# 假设有两个文件 old.txt 和 new.txt
compare_files_unified('old.txt', 'new.txt')
可视化版:逐行打印带标记的差异(自定义输出格式)
import difflib
def compare_files_detailed(file1_path, file2_path):
"""
逐行对比并打印带有标记的结果
+ : 新增行 (在 file2 中,不在 file1 中)
- : 删除行 (在 file1 中,不在 file2 中)
: 相同行
? : 行内差异 (标记有改动的字符)
"""
with open(file1_path, 'r', encoding='utf-8') as f1, \
open(file2_path, 'r', encoding='utf-8') as f2:
lines1 = f1.readlines()
lines2 = f2.readlines()
# 使用 Differ 类进行行级对比
differ = difflib.Differ()
diff = list(differ.compare(lines1, lines2))
print(f"对比结果 ({file1_path} vs {file2_path}):")
print("=" * 60)
for line in diff:
if line.startswith('+ '):
print(f"\033[92m{line}\033[0m", end='') # 绿色表示新增
elif line.startswith('- '):
print(f"\033[91m{line}\033[0m", end='') # 红色表示删除
elif line.startswith('? '):
print(f"\033[93m{line}\033[0m", end='') # 黄色表示行内改动
else:
print(f" {line}", end='') # 普通行
# 示例用法
compare_files_detailed('old.txt', 'new.txt')
JavaScript 实现(适合 Node.js 或前端)
如果需要在浏览器或 Node.js 中进行对比,可以使用 diff 这个 npm 包,或者手动实现一个简单的 LCS。
使用 diff 库(推荐,最方便)
首先安装依赖:
npm install diff
// fileDiff.js
const fs = require('fs');
const Diff = require('diff');
function compareFiles(file1Path, file2Path) {
// 读取文件内容
const oldContent = fs.readFileSync(file1Path, 'utf8');
const newContent = fs.readFileSync(file2Path, 'utf8');
// 执行逐行对比
const changes = Diff.diffLines(oldContent, newContent);
// 输出结果
changes.forEach(part => {
// value: 行的内容
// added: 是否是新增
// removed: 是否是删除
const prefix = part.added ? '+' : (part.removed ? '-' : ' ');
// 在控制台用颜色区分
if (part.added) {
console.log(`\x1b[32m${prefix} ${part.value}\x1b[0m`); // 绿色
} else if (part.removed) {
console.log(`\x1b[31m${prefix} ${part.value}\x1b[0m`); // 红色
} else {
console.log(`${prefix} ${part.value}`);
}
});
}
// 使用
compareFiles('old.txt', 'new.txt');
前端展示差异(HTML 版本)
// 假设有两个字符串
const oldStr = "第一行\n第二行\n第三行";
const newStr = "第一行\n修改的第二行\n第四行";
// 使用 diff 库 (需要 <script src="diff.js"></script>)
const changes = Diff.diffLines(oldStr, newStr);
// 生成 HTML 用于展示
let displayHtml = '';
changes.forEach(part => {
const color = part.added ? 'lightgreen' : (part.removed ? 'lightcoral' : 'white');
// 注意:需要将文本中的 \n 转换为 <br> 才能正常显示换行
const text = part.value.replace(/\n/g, '<br>');
displayHtml += `<div style="background-color: ${color}; padding: 2px 5px; margin: 2px 0;">
<span style="font-weight: bold; color: ${part.added ? 'green' : (part.removed ? 'red' : 'gray')};">
${part.added ? '+' : (part.removed ? '-' : ' ')}
</span>
${text}
</div>`;
});
document.getElementById('diffContainer').innerHTML = displayHtml;
命令行调用(最省事)
如果你的脚本只是需要简单的执行 diff 命令并获取结果,可以直接使用子进程调用系统命令。
Python 调用系统 diff
import subprocess
import sys
def diff_system(file1, file2):
try:
# 调用系统 diff 命令,-u 表示 unified 格式,-w 忽略空白
result = subprocess.run(
['diff', '-u', file1, file2],
capture_output=True,
text=True,
check=False # 有差异时不抛出异常
)
if result.returncode == 0:
print("两个文件完全相同")
else:
print(result.stdout)
except FileNotFoundError:
print("系统中未找到 diff 命令 (Linux/Mac 默认有,Windows 需要 Git Bash 等)", file=sys.stderr)
# 使用
diff_system('old.txt', 'new.txt')
使用建议
| 场景 | 推荐方案 |
|---|---|
| Python 脚本 | difflib (内置库,无依赖) |
| Node.js 项目 | diff npm 包 (功能全面) |
| 前端可视化 | diff 库 + 自定义 CSS |
| 快速验证 / 终端工具 | 调用系统 diff 命令 |
| 大文件(百 MB 以上) | 使用 git diff --no-index 或分块读取 |
文件差异对比的核心概念解释
- 逐行对比:将文件视为行的数组。
- 上下文:
unified diff在差异前后显示几行未修改的行,便于理解上下文。 - 最长公共子序列:算法的基础,找出两个序列中相同的部分,剩下的就是差异。
- Myers 算法:
git使用的算法,通常比基础的 LCS 更快,输出更紧凑。
希望这些代码能直接帮到你!根据你的实际需求(终端输出、前端展示、还是云端处理),选择最合适的一种即可。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播