检查(在单元测试中)二进制文件A和B是否相等的最简单方法是什么?
答案 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
。