Java:如何检查2个二进制文件是否相同?

时间:2014-04-02 17:20:24

标签: java

检查(在单元测试中)二进制文件A和B是否相等的最简单方法是什么?

7 个答案:

答案 0 :(得分:11)

第三方图书馆是公平游戏吗?番石榴有Files.equal(File, File)。如果你不必要,就没有理由去打哈希;它只会效率低下。

答案 1 :(得分:5)

总是只是逐个字节地从每个文件中读取并逐个比较它们。 Md5和Sha1等仍然必须读取所有字节,因此计算哈希是额外的工作,你不必这样做。

if(file1.length() != file2.length()){
        return false;
 }

 try(   InputStream in1 =new BufferedInputStream(new FileInputStream(file1));
    InputStream in2 =new BufferedInputStream(new FileInputStream(file2));
 ){

      int value1,value2;
      do{
           //since we're buffered read() isn't expensive
           value1 = in1.read();
           value2 = in2.read();
           if(value1 !=value2){
           return false;
           }
      }while(value1 >=0);

 //since we already checked that the file sizes are equal 
 //if we're here we reached the end of both files without a mismatch
 return true;
}

答案 2 :(得分:3)

使用assertBinaryEquals。

public static void assertBinaryEquals(java.io.File expected, java.io.File actual)

http://junit-addons.sourceforge.net/junitx/framework/FileAssert.html

答案 3 :(得分:3)

读取(小)块中的文件并进行比较:

static boolean binaryDiff(File a, File b) throws IOException {
    if(a.length() != b.length()){
        return false;
    }

    final int BLOCK_SIZE = 128;
    InputStream aStream = new FileInputStream(a);
    InputStream bStream = new FileInputStream(b);
    byte[] aBuffer = new byte[BLOCK_SIZE];
    byte[] bBuffer = new byte[BLOCK_SIZE];
    while (true) {
        int aByteCount = aStream.read(aBuffer, 0, BLOCK_SIZE);
        bStream.read(bBuffer, 0, BLOCK_SIZE);
        if (aByteCount < 0) {
            return true;
        }
        if (!Arrays.equals(aBuffer, bBuffer)) {
            return false;
        }
    }
}

答案 4 :(得分:2)

如果你想避免依赖,你可以很好地使用Files.readAllBytes和Assert.assertArrayEquals

Assert.assertArrayEquals("Binary files differ", 
    Files.readAllBytes(Paths.get(expectedBinaryFile)), 
    Files.readAllBytes(Paths.get(actualBinaryFile)));

注意:这将读取整个文件,因此对于大文件可能效率不高。

答案 5 :(得分:1)

我也必须在单元测试中做同样的事情,所以我使用SHA1哈希来做到这一点,为了节省哈希的计算我检查文件大小是否相等。这是我的尝试:

public class SHA1Compare {
    private static final int CHUNK_SIZE = 4096;

    public void assertEqualsSHA1(String expectedPath, String actualPath) throws IOException, NoSuchAlgorithmException {
        File expectedFile = new File(expectedPath);
        File actualFile = new File(actualPath);
        Assert.assertEquals(expectedFile.length(), actualFile.length());
        try (FileInputStream fisExpected = new FileInputStream(actualFile);
                FileInputStream fisActual = new FileInputStream(expectedFile)) {
            Assert.assertEquals(makeMessageDigest(fisExpected), 
                    makeMessageDigest(fisActual));
        }
    }

    public String makeMessageDigest(InputStream is) throws NoSuchAlgorithmException, IOException {
        byte[] data = new byte[CHUNK_SIZE];
        MessageDigest md = MessageDigest.getInstance("SHA1");
        int bytesRead = 0;
        while(-1 != (bytesRead = is.read(data, 0, CHUNK_SIZE))) {
            md.update(data, 0, bytesRead);
        }
        return toHexString(md.digest());
    }

    private String toHexString(byte[] digest) {
        StringBuilder sha1HexString = new StringBuilder();
        for(int i = 0; i < digest.length; i++) {
            sha1HexString.append(String.format("%1$02x", Byte.valueOf(digest[i])));
        }
        return sha1HexString.toString();
    }
}

答案 6 :(得分:1)

自Java 12起,您还可以使用Files.mismatch方法JavaDoc。如果文件相同,它将返回-1L