developer tip

두 파일이 동일한 콘텐츠를 저장하는지 확인

optionbox 2020. 12. 4. 08:07
반응형

두 파일이 동일한 콘텐츠를 저장하는지 확인


boolean sameContent(Path file1,Path file2)주어진 두 경로가 동일한 내용을 저장하는 파일을 가리키는 지 결정 하는 Java 함수 어떻게 작성 합니까? 물론 먼저 파일 크기가 같은지 확인합니다. 이는 동일한 콘텐츠를 저장하는 데 필요한 조건입니다. 그러나 나는 당신의 접근 방식을 듣고 싶습니다. 두 파일이 동일한 하드 드라이브에 저장되어있는 경우 (대부분의 경우와 같이) 두 스트림 사이를 너무 많이 건너 뛰는 가장 좋은 방법은 아닐 것입니다.


정확히 어떤 FileUtils.contentEquals방법 아파치의 평민 IO는 않습니다 및 API는 여기 .

다음과 같이 시도하십시오.

File file1 = new File("file1.txt");
File file2 = new File("file2.txt");
boolean isTwoEqual = FileUtils.contentEquals(file1, file2);

실제로 비교를 수행하기 전에 다음 검사를 수행합니다.

  • 두 파일의 존재
  • 전달되는 두 파일 모두 디렉토리가 아닌 파일 유형이어야합니다.
  • 길이 (바이트)는 동일하지 않아야합니다.
  • 둘 다 다른 파일이며 하나도 같지 않습니다.
  • 그런 다음 내용을 비교하십시오.

외부 라이브러리를 사용하지 않으려면 파일을 바이트 배열로 읽고 비교하기 만하면됩니다 (Java-7 이전에서는 작동하지 않음).

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

Arrays.equals 를 사용하여 .

파일이 큰 경우 전체 파일을 배열로 읽는 대신 여기에BufferedInputStream 설명 된대로 파일을 덩어리별로 읽고 읽어야합니다 .


파일이 작 으면 둘 다 메모리로 읽고 바이트 배열을 비교할 수 있습니다.

파일이 작지 않은 경우 콘텐츠 (예 : 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;
}

문제와 함께 당신을 도울해야합니다 :

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

Java 12부터 파일 내용에 불일치가없는 경우 반환 하는 Files.mismatch 메서드 -1가 있습니다. 따라서 함수는 다음과 같습니다.

private static boolean sameContent(Path file1, Path file2) throws IOException {
    return Files.mismatch(file1, file2) == -1;
}

package test;  

      import org.junit.jupiter.api.Test;

      import java.io.IOException;
      import java.nio.file.FileSystems;
      import java.nio.file.Files;
      import java.nio.file.Path;

import static org.junit.Assert.assertEquals;

public class CSVResultDIfference {

   @Test
   public void csvDifference() throws IOException {
       Path file_F = FileSystems.getDefault().getPath("C:\\Projekts\\csvTestX", "yolo2.csv");
       long size_F = Files.size(file_F);
       Path file_I = FileSystems.getDefault().getPath("C:\\Projekts\\csvTestZ", "yolo2.csv");
       long size_I = Files.size(file_I);
       assertEquals(size_F, size_I);

   }
}

그것은 나를 위해 일했습니다 :)

참고 URL : https://stackoverflow.com/questions/27379059/determine-if-two-files-store-the-same-content

반응형