java - معنى - diffchecker




حدد ما إذا كان الملفان يخزنان نفس المحتوى (4)

كيف تكتب دالة جافا boolean sameContent(Path file1,Path file2) الذي يحدد ما إذا كان boolean sameContent(Path file1,Path file2) يشيران إلى الملفات التي تخزن نفس المحتوى؟ بالطبع ، أولا ، أود أن أتحقق مما إذا كانت أحجام الملفات هي نفسها. هذا شرط ضروري لتخزين نفس المحتوى. ولكن بعد ذلك أود الاستماع إلى أساليبك. إذا تم تخزين الملفين على نفس القرص الصلب (كما هو الحال في معظم حالاتي) ، فربما لا تكون أفضل طريقة للقفز مرات كثيرة بين الدارين.


إذا كانت الملفات صغيرة ، يمكنك قراءة كل منهما في الذاكرة ومقارنة صفائف البايت.

إذا لم تكن الملفات صغيرة ، يمكنك إما حساب التجزئة الخاصة بمحتواها (على سبيل المثال MD5 أو SHA-1) واحدة تلو الأخرى ومقارنة التجزئات (لكن هذا يترك فرصة ضئيلة جدًا للخطأ) ، أو يمكنك مقارنة المحتوى ولكن لهذا لا يزال عليك قراءة التدفقات المتبدلة.

هنا مثال:

boolean sameContent(Path file1, Path file2) throws IOException {
    final long size = Files.size(file1);
    if (size != Files.size(file2))
        return false;

    if (size < 4096)
        return Arrays.equals(Files.readAllBytes(file1), Files.readAllBytes(file2));

    try (InputStream is1 = Files.newInputStream(file1);
         InputStream is2 = Files.newInputStream(file2)) {
        // Compare byte-by-byte.
        // Note that this can be sped up drastically by reading large chunks
        // (e.g. 16 KBs) but care must be taken as InputStream.read(byte[])
        // does not neccessarily read a whole array!
        int data;
        while ((data = is1.read()) != -1)
            if (data != is2.read())
                return false;
    }

    return true;
}

إذا كنت لا ترغب في استخدام أي مكتبات خارجية ، فما عليك سوى قراءة الملفات إلى صفائف البايت ومقارنتها (لن تعمل قبل Java-7):

byte[] f1 = Files.readAllBytes(file1);
byte[] f2 = Files.readAllBytes(file2);

باستخدام Arrays.equals .

إذا كانت الملفات كبيرة ، فبدلاً من قراءة الملفات بأكملها إلى صفائف ، يجب استخدام BufferedInputStream وقراءة الملفات بفعل المقاطع كما هو موضح here .


كان لدي سيناريو حيث اضطررت لمقارنة أي ملفين (أشرطة الفيديو / الصور / أي شيء). ذهبت إلى الأمام في حساب MD5 للملفين ومقارنة لهم. انها عملت بشكل جيد.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5EncoderUtility {
    public String encodeToMd5(String filePath) {

        MessageDigest md = null;
        try {
            md = MessageDigest.getInstance("SHA1");
        } catch (NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        }
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(filePath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        byte[] dataBytes = new byte[1024];

        int nread = 0;

        try {
            while ((nread = fis.read(dataBytes)) != -1) {
                md.update(dataBytes, 0, nread);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        byte[] mdbytes = md.digest();

        // convert the byte to hex format
        StringBuffer sb = new StringBuffer("");
        for (int i = 0; i < mdbytes.length; i++) {
            sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
        }

        System.out.println("Digest(in hex format):: " + sb.toString());
        return sb.toString();
    }
}
public class FileCompareUtility {
    MD5EncoderUtility md5EncoderUtil = new MD5EncoderUtility();

    public boolean compare2Files(String actualFilePath, String expectedFilePath) {
        if ((md5EncoderUtil.encodeToMd5(actualFilePath)).equals(md5EncoderUtil.encodeToMd5(expectedFilePath))) {
            System.out.println("The files- "+actualFilePath+" and "+expectedFilePath+" are same");
            return true;
        } else {
            System.out.println("The files- "+actualFilePath+" and "+expectedFilePath+" are NOT same");
            return false;
        }
    }

}

ويمكن أن يطلق على هذا النحو:

        String actualFileComparePath = "D:/Videos/test.mp4";
        String expectedFileComparePath = "D:/Videos/test2.mp4";

// This will compare any types of files- here video.Eg-Video
        fileCompareUtil.compare2Files(actualFileComparePath, expectedFileComparePath);

يجب أن يساعدك This حل مشكلتك:

package test;

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;

public class CompareFileContents {

    public static void main(String[] args) throws IOException {

        File file1 = new File("test1.txt");
        File file2 = new File("test2.txt");
        File file3 = new File("test3.txt");

        boolean compare1and2 = FileUtils.contentEquals(file1, file2);
        boolean compare2and3 = FileUtils.contentEquals(file2, file3);
        boolean compare1and3 = FileUtils.contentEquals(file1, file3);

        System.out.println("Are test1.txt and test2.txt the same? " + compare1and2);
        System.out.println("Are test2.txt and test3.txt the same? " + compare2and3);
        System.out.println("Are test1.txt and test3.txt the same? " + compare1and3);
    }
}




comparison