-4

问题:有没有更好的方法来比较两个小尺寸(100Kb)文件,同时选择性地忽略文本的某个部分。并报告差异

寻找默认/现有的 java 库或任何 Windows 本机应用程序

下面是场景:

预期文件 1 位于 D:\expected\FileA_61613.txt  
..实际文件 2 位于 D:\actuals\FileA_61613.txt

预期文件中的内容

这里有一些第一行


可能有空格、换行符、缩进,这是另一行

键:SomeValue
日期 : 01/02/2012
时间:18:20
键2:值2
键 3:值 3
键 4:值 4
键 5:值 5

其他一些文本再次表明他是这个文件的结尾。

要比较的实际文件:

这里有一些第一行


可能有空格、换行符、缩进,这是另一行

键:SomeValue
日期 : 18/09/2013
时间戳:15:10.345+10.00
键2:值2
键 3:值 3
key4:不同的东西
键 5:值 5


其他一些文本再次表明他是这个文件的结尾。

文件 1 和 2 需要逐行比较。不忽略
空格、缩进、换行符

比较结果应如下所示:
第 8 行 - 预期时间,但实际时间戳
第 8 行 - 预期 HH.mm,但实际 HH.mm .345+10.00
第 10 行 - 预期值 4,但实际有所不同。
第 11 行 - 预期缩进 N 个空格,但实际上只有 X 个空格
第 13 行 - 预期有换行符,但不存在换行符。

下面也发生了变化,但应该被忽略
第 7 行 - 预计 01/02/2012,但实际 18/09/2013(准确且只有 10 个字符)
第 8 行 - 预计 18:20 但实际:15:20(准确且仅5 个字符应忽略)
注意:应报告剩余的.345+10.00

即使结果只包含行号并且没有分析失败的原因也很好。
但它不应该只在第 8 行报告失败并退出。
它应该报告所有的变化,除了排除的“日期”和“时间”值。

一些搜索结果指向使用 Perl 的解决方案。
但正在寻找 Java / Javascript 解决方案。解决方案的输入将是两个文件的完整文件路径。

我目前的解决方法:
将要忽略的文本替换为“#”。在进行比较时,如果遇到#,不要认为是差异。下面是我的工作代码。但我需要知道我是否可以使用一些默认/现有的库或函数来实现这一点。

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class fileComparison {
    public static void main(String[] args) throws IOException {
        FileInputStream fstream1 = new FileInputStream(
                "D:\\expected\\FileA_61613.txt");
        FileInputStream fstream2 = new FileInputStream(
                "D:\\actuals\\FileA_61613.txt");
        DataInputStream in1 = new DataInputStream(fstream1);
        BufferedReader br1 = new BufferedReader(new InputStreamReader(in1));
        DataInputStream in2 = new DataInputStream(fstream2);
        BufferedReader br2 = new BufferedReader(new InputStreamReader(in2));
        int lineNumber = 0;
        String strLine1 = null;
        String strLine2 = null;
        StringBuilder sb = new StringBuilder();
        System.out.println(sb);
        boolean isIgnored = false;

        while (((strLine1 = br1.readLine()) != null)
                && ((strLine2 = br2.readLine()) != null)) {
            lineNumber++;
            if (!strLine1.equals(strLine2)) {
                int strLine1Length = strLine1.length();
                int strLine2Length = strLine2.length();
                int maxIndex = Math.min(strLine1Length, strLine2Length);
                if (maxIndex == 0) {
                    sb.append("Mismatch at line " + lineNumber
                            + " all characters " + '\n');
                    break;
                }
                int i;
                for (i = 0; i < maxIndex; i++) {
                    if (strLine1.charAt(i) == '#') {
                        isIgnored = true;
                        continue;
                    }
                    if (strLine1.charAt(i) != strLine2.charAt(i)) {
                        isIgnored = false;
                        break;
                    }
                }
                if (isIgnored) {
                    sb.append("Ignored line " + lineNumber + '\n');
                } else {
                    sb.append("Mismatch at line " + lineNumber + " at char "
                            + i + '\n');
                }
            }
        }
        System.out.println(sb.toString());
        br1.close();
        br2.close();

    }
}

我能够得到输出:

Ignored line 7
Mismatch at line 8 at char 4
Mismatch at line 11 at char 13
Mismatch at line 12 at char 8
Mismatch at line 14 all characters 

但是,当同一行中有多个差异时。我无法将它们全部记录下来,因为我是逐字符比较,而不是逐字比较。
我不喜欢逐字比较,因为我认为不可能比较换行符和空格。我的理解对吗?

4

1 回答 1

0

java.lang.StringIndexOutOfBoundsException来自这段代码:

for (int i = 0; i < strLine1.length(); i++) {
   if (strLine1.charAt(i) != strLine2.charAt(i)) {
       System.out.println("char not same at " + i);
   }   
}

当您将较大的StringstrLine 滚动到索引时,该索引大于 strLine2 的长度(第二个文件小于第一个文件),您会得到该异常。它来了,因为 strLine2 在较短时在这些索引上没有值。

于 2013-09-18T14:03:35.843 回答