差异
举一个最常见的例子,我们使用git进行提交时,通常会使用 git diff --cached
来查看这次提交做了哪些改动,这里我们先简单定义一下什么是diff:
diff就是目标文本和源文本之间的区别,也就是将源文本变成目标文本所需要的操作。
差异算法
在 Git 中,有四种diff算法,分别是Myers、Minimal、Patience和Histogram,它们用于获取位于两个不同提交中的两个相同文件的差异。
Myers算法由Eugene W.Myers在1986年发表的一篇论文中提出,是一个能在大部分情况产生”最短的直观的“diff的一个算法。
文本差异对比涉及到的算法介绍:
How different are different diff algorithms in Git
对比工具
好用的在线文本对比: 在线文本比较工具
好用的桌面文本对比软件:
Meld、
差异库
使用例子
maven
<dependency>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils</artifactId>
<version>4.11</version>
</dependency>
文本
- test1.txt 和 test3.txt
_this.ispc = function(){
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone",
"SymbianOS", "Windows Phone",
"iPad", "iPod"];
var flag = true;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
break;
}
}
return flag;
}
window._assignInfo = {};
window._curnodepersons = [];
window.attachmode = '0';
window.isEsignature = false;
window.upList = [];
window.downList = [];
window.billId = '';
window.upProcessIdList = [];
window.downProcessIdList = [];
var urlsplit = window.location.href.split("#");
if(urlsplit.length>1){
//alert(window.location.href);
location.href = urlsplit[0];
}
- test2.txt
_this.ispc = function(){
var userAgentInfo = navigator.userAgent;
var Agents = ["Android", "iPhone",
"SymbianOS", "Windows Phone",
"iPad", "iPod"];
var flag = true;
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false;
insert1;
insert2;
break;
}
}
return flag;
}
window._assignInfo = {};
window._curnodepersons = [];
window.attachmode = '0';
window.isEsignature = false;
add
window.billId = '';
window.upProcessIdList = [];
window.downProcessIdList = [];
var urlsplit = window.location.href.split("#");
if(urlsplit.length>1){
//alert(window.location.href);
location.href = qazwer[0];
}
获取两文件的不同点-patch
//原始文件
List<String> original = Files.readAllLines(new File("D:\\test1.txt").toPath());
//对比文件
List<String> revised = Files.readAllLines(new File("D:\\test2.txt").toPath());
//两文件的不同点
Patch<String> patch = DiffUtils.diff(original, revised);
for (AbstractDelta<String> delta : patch.getDeltas()) {
System.out.println(delta);
}
输出:
[InsertDelta, position: 9, lines: [insert1;, insert2;]]
[ChangeDelta, position: 18, lines: [window.upList = [];, window.downList = [];] to [, , add]]
[ChangeDelta, position: 26, lines: [ location.href = urlsplit[0];] to [ location.href = qazwer[0];]]
InsertDelta代表插入的,ChangeDelta代表删除的或修改的。position代表第几行,lines代表内容。
根据patch生成统一的差异格式unifiedDiff
//原始文件
List<String> original = Files.readAllLines(new File("D:\\test1.txt").toPath());
//对比文件
List<String> revised = Files.readAllLines(new File("D:\\test2.txt").toPath());
//两文件的不同点
Patch<String> patch = DiffUtils.diff(original, revised);
//生成统一的差异格式
List<String> unifiedDiff = UnifiedDiffUtils.generateUnifiedDiff("test1.txt", "test2.txt", original, patch, 0);
unifiedDiff.forEach(System.out::println);
输出 diff:
--- test1.txt
+++ test2.txt
@@ -10,0 +10,2 @@
+insert1;
+insert2;
@@ -19,2 +21,3 @@
-window.upList = [];
-window.downList = [];
+
+
+add
@@ -27,1 +30,1 @@
- location.href = urlsplit[0];
+ location.href = qazwer[0];
前端页面美化输出:
如果想将上面通过Java代码得到的两个文件的差异美化输出可以 参考我另一篇博客:
Java+html实现文本对比 实现效果如下:
小结
多思考。