Java: Comment vérifier que 2 fichiers binarys sont identiques?

Quel est le moyen le plus simple de vérifier (dans un test unitaire) si les fichiers binarys A et B sont égaux?

Les bibliothèques tierces sont-elles un jeu équitable? Goyave a Files.equal(File, File) . Il n’y a pas vraiment de raison de s’embêter avec le hachage si vous n’y êtes pas obligé. cela ne peut être que moins efficace.

Il y a toujours juste lire octet par octet dans chaque fichier et les comparer au fur et à mesure. Md5 et Sha1, etc. doivent encore lire tous les octets, donc calculer le hachage est un travail supplémentaire que vous n’avez pas à faire.

 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; } 

Avec assertBinaryEquals.

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

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

Lisez les fichiers en (petits) blocs et comparez-les:

 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; } } } 

Si vous voulez éviter les dépendances, vous pouvez le faire très facilement avec Files.readAllBytes et Assert.assertArrayEquals

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

Remarque: Ceci lira tout le fichier, ce qui pourrait ne pas être efficace avec les gros fichiers.

Je devais faire la même chose dans un test unitaire aussi, donc j’ai utilisé des hachages SHA1 pour le faire, afin d’épargner le calcul des hachages que je vérifie si les tailles de fichiers sont égales d’abord. Voici ma tentative:

 public class SHA1Compare { private static final int CHUNK_SIZE = 4096; public void assertEqualsSHA1(Ssortingng expectedPath, Ssortingng 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 Ssortingng 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 toHexSsortingng(md.digest()); } private Ssortingng toHexSsortingng(byte[] digest) { SsortingngBuilder sha1HexSsortingng = new SsortingngBuilder(); for(int i = 0; i < digest.length; i++) { sha1HexString.append(String.format("%1$02x", Byte.valueOf(digest[i]))); } return sha1HexString.toString(); } }