用Java生成格式化的diff输出 [英] Generate formatted diff output in Java
问题描述
是否有适用于Java的库可以接受两个字符串,并根据* nix diff命令返回带格式化输出的字符串?
Are there any libraries out there for Java that will accept two strings, and return a string with formatted output as per the *nix diff command?
例如。喂入
test 1,2,3,4
test 5,6,7,8
test 9,10,11,12
test 13,14,15,16
和
test 1,2,3,4
test 5,6,7,8
test 9,10,11,12,13
test 13,14,15,16
as输入,它会给你
test 1,2,3,4 test 1,2,3,4
test 5,6,7,8 test 5,6,7,8
test 9,10,11,12 | test 9,10,11,12,13
test 13,14,15,16 test 13,14,15,16
与我将文件传递给 diff -y预期实际
我找到了这个问题,并提供了一些很好的建议在一般库上给你编程输出,但我想要直字符串结果。
I found this question, and it gives some good advice on general libraries for giving you programmatic output, but I'm wanting the straight string results.
我可以调用 diff
直接作为系统调用,但这个特定的应用程序将在unix和windows上运行,我无法确定环境实际上是否有 diff
可用。
I could call diff
directly as a system call, but this particular app will be running on unix and windows and I can't be sure that the environment will actually have diff
available.
推荐答案
我最后自己动手了。不确定它是否是最好的实现,并且它很丑陋,但它会通过测试输入。
I ended up rolling my own. Not sure if it's the best implementation, and it's ugly as hell, but it passes against test input.
它使用 java-差异做重型差异提升(任何apache公共StrBuilder和StringUtils而不是库存Java StringBuilder)
It uses java-diff to do the heavy diff lifting (any apache commons StrBuilder and StringUtils instead of stock Java StringBuilder)
public static String diffSideBySide(String fromStr, String toStr){
// this is equivalent of running unix diff -y command
// not pretty, but it works. Feel free to refactor against unit test.
String[] fromLines = fromStr.split("\n");
String[] toLines = toStr.split("\n");
List<Difference> diffs = (new Diff(fromLines, toLines)).diff();
int padding = 3;
int maxStrWidth = Math.max(maxLength(fromLines), maxLength(toLines)) + padding;
StrBuilder diffOut = new StrBuilder();
diffOut.setNewLineText("\n");
int fromLineNum = 0;
int toLineNum = 0;
for(Difference diff : diffs) {
int delStart = diff.getDeletedStart();
int delEnd = diff.getDeletedEnd();
int addStart = diff.getAddedStart();
int addEnd = diff.getAddedEnd();
boolean isAdd = (delEnd == Difference.NONE && addEnd != Difference.NONE);
boolean isDel = (addEnd == Difference.NONE && delEnd != Difference.NONE);
boolean isMod = (delEnd != Difference.NONE && addEnd != Difference.NONE);
//write out unchanged lines between diffs
while(true) {
String left = "";
String right = "";
if (fromLineNum < (delStart)){
left = fromLines[fromLineNum];
fromLineNum++;
}
if (toLineNum < (addStart)) {
right = toLines[toLineNum];
toLineNum++;
}
diffOut.append(StringUtils.rightPad(left, maxStrWidth));
diffOut.append(" "); // no operator to display
diffOut.appendln(right);
if( (fromLineNum == (delStart)) && (toLineNum == (addStart))) {
break;
}
}
if (isDel) {
//write out a deletion
for(int i=delStart; i <= delEnd; i++) {
diffOut.append(StringUtils.rightPad(fromLines[i], maxStrWidth));
diffOut.appendln("<");
}
fromLineNum = delEnd + 1;
} else if (isAdd) {
//write out an addition
for(int i=addStart; i <= addEnd; i++) {
diffOut.append(StringUtils.rightPad("", maxStrWidth));
diffOut.append("> ");
diffOut.appendln(toLines[i]);
}
toLineNum = addEnd + 1;
} else if (isMod) {
// write out a modification
while(true){
String left = "";
String right = "";
if (fromLineNum <= (delEnd)){
left = fromLines[fromLineNum];
fromLineNum++;
}
if (toLineNum <= (addEnd)) {
right = toLines[toLineNum];
toLineNum++;
}
diffOut.append(StringUtils.rightPad(left, maxStrWidth));
diffOut.append("| ");
diffOut.appendln(right);
if( (fromLineNum > (delEnd)) && (toLineNum > (addEnd))) {
break;
}
}
}
}
//we've finished displaying the diffs, now we just need to run out all the remaining unchanged lines
while(true) {
String left = "";
String right = "";
if (fromLineNum < (fromLines.length)){
left = fromLines[fromLineNum];
fromLineNum++;
}
if (toLineNum < (toLines.length)) {
right = toLines[toLineNum];
toLineNum++;
}
diffOut.append(StringUtils.rightPad(left, maxStrWidth));
diffOut.append(" "); // no operator to display
diffOut.appendln(right);
if( (fromLineNum == (fromLines.length)) && (toLineNum == (toLines.length))) {
break;
}
}
return diffOut.toString();
}
private static int maxLength(String[] fromLines) {
int maxLength = 0;
for (int i = 0; i < fromLines.length; i++) {
if (fromLines[i].length() > maxLength) {
maxLength = fromLines[i].length();
}
}
return maxLength;
}
这篇关于用Java生成格式化的diff输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!