Java - 比较具有奇怪内容的文件中的字节

时间:2011-09-08 23:25:33

标签: java

我有一个数据库转储程序,它以非常特定的格式写出表的平面文件。我现在需要对我们的旧程序进行测试,并确认生成的文件是相同的。手动执行此操作很痛苦,因此我需要编写一些单元测试。

我需要逐个字节地比较两个文件内容,并看到第一个区别。问题是他们有各种各样的疯狂字节,CF / LF / null等等遍布整个过程。

以下是来自Scite的两个文件的屏幕截图,为您提供一个想法:

http://imageshack.us/photo/my-images/840/screenshot1xvt.png/

确认每个字节对应的最佳策略是什么?

3 个答案:

答案 0 :(得分:5)

Apache Commons IOFileUtils.contentEquals(File file1, File file2)方法似乎可以做你想要的。优点:

  • 看起来效率很高 - 使用缓冲流读取文件内容,如果长度不同,甚至不打开文件。
  • 便利。

缺点:

  • 不会告诉您有关差异的详细信息。这听起来就像你想要的那样。

我想说你最好的选择就是下载源代码,查看他们正在做什么,然后增强它以打印出行号。困难的部分是弄清楚你在哪条线上。通过在字节级别读取,您必须明确检查\r\n\r\n,然后递增自己的“行号”计数器。我也不知道你会遇到什么样的i18n问题(如果有的话)。

答案 1 :(得分:3)

class DominicFile {

    static boolean equalfiles(File f1, File f2) {
        byte[] b1 = getBytesFromFile(f1);
        byte[] b2 = getBytesFromFile(f2);

        if(b1.length != b2.length) return false;
        for(int i = 0; i < b1.length; i++) {
            if(b1[i] != b2[i]) return false;
        }
        return true;
    }

    // returns the index (0 indexed) of the first difference, or -1 if identical
    // fails for files 2G or more due to limitations of "int"... use long if needed
    static int firstDiffBetween(File f1, File f2) {
        byte[] b1 = getBytesFromFile(f1);
        byte[] b2 = getBytesFromFile(f2);

        int shortest = b1.length;
        if(b2.length < shortest) shortest = b2.length;
        for(int i = 0; i < shortest; i++) {
            if(b1[i] != b2[i]) return i;
        }
        return -1;
    }

    // Returns the contents of the file in a byte array.
    // shamelessly stolen from http://www.exampledepot.com/egs/java.io/file2bytearray.html
    public static byte[] getBytesFromFile(File file) throws IOException {
        InputStream is = new FileInputStream(file);

        // Get the size of the file
        long length = file.length();

        // You cannot create an array using a long type.
        // It needs to be an int type.
        // Before converting to an int type, check
        // to ensure that file is not larger than Integer.MAX_VALUE.
        if (length > Integer.MAX_VALUE) {
            // File is too large
        }

        // Create the byte array to hold the data
        byte[] bytes = new byte[(int)length];

        // Read in the bytes
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length
               && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
            offset += numRead;
        }

        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            throw new IOException("Could not completely read file "+file.getName());
        }

        // Close the input stream and return bytes
        is.close();
        return bytes;
    }


}

答案 2 :(得分:0)

为什么不进行MD5校验和,例如描述here

的校验和