2017-11-30 10 views
-1

현재 소프트웨어에서 생성 된 결과 테스트 파일과 기준 파일을 비교하는 야간 자동화 작업이 있습니다. 이 비교는 여러 번 수행되며 파일이 큽니다. 파일 비교는 테스트 자동화의 병 목입니다.Java에서 두 개의 큰 파일을 비교하는 가장 빠른 방법은 무엇입니까

파일 비교는 현재 라인 비교를 통한 버퍼링을 통해 수행됩니다.

두 파일의 체크섬 비교를 수행하려고했습니다 (체크섬이 일치하지 않으면 줄 단위로 줄을 검사). 이것이 최선의 접근 방법입니까? 누군가 제안하고 싶은 공공 도서관이 있습니까? 충분히 두 260K 파일을 비교

감사

+0

파일이 동일하거나 다르지 않아야합니까? 차이점을 확인해야합니까? – AntonH

+1

"큰"을 정의하십시오. 체크섬을 비교하는 것은 이미 계산 된 경우 가장 좋은 방법입니다. 먼저 계산해야하는 경우 가장 적은 영향을 미치는 방식입니다. – luk2302

+1

파일 크기를 확인하여 시작할 수 있습니다. 일치하지 않으면 전체 파일의 체크섬도 균등 함을 확인하는 좋은 방법입니다 –

답변

1

10 밀리 좋은가요? (Windows 랩톱에서)

그렇다면 java.security.DigestInputStream을 사용하여 해시를 계산하고 비교할 수 있습니다.

물론 파일의 길이를 먼저 확인하십시오. 문제가 많은 파일에 대한 비교가 필요한 경우 병렬 스레드를 사용하여 각 쌍을 비교하는 것을 고려하십시오.

샘플 코드 : getMessageDigest()이 가장 많은 시간 비용이 많이 드는 작업이다가

public static void main(String[] args) { 

    try { 
     File file1 = new File("D:\\tmp\\tests\\logs\\test.log"); 
     File file2 = new File("D:\\tmp\\tests\\logs\\test-cp.log"); 

     if (!file1.exists() || !file2.exists()) { 
      System.out.println("One of the file not found."); 
      return; 
     } 
     if (file1.length() != file2.length()) { 
      System.out 
        .println("Files are not identical - not equal length."); 
      return; 
     } 

     long f1Length = file1.length(); 
     long f2Length = file2.length(); 

     System.out.println("Check Digest method:"); 
     FileInputStream fis1 = new FileInputStream(file1); 
     DigestInputStream dgStream1 = new DigestInputStream(fis1, 
       MessageDigest.getInstance("MD5")); 
     FileInputStream fis2 = new FileInputStream(file2); 
     DigestInputStream dgStream2 = new DigestInputStream(fis2, 
       MessageDigest.getInstance("MD5")); 
     // most expensive is dgStream1.getMessageDigest() so do it only at last read 
     dgStream1.on(false); 
     dgStream2.on(false); 

     long f1ReadTotal = 0; 
     long f2ReadTotal = 0; 

     long start = System.nanoTime(); 

     int read = 0; 
     byte[] buff = new byte[1024 * 128]; 
     do { 
      if ((f1Length - f1ReadTotal) < (1024 * 128)) { 
       // last read 
       dgStream1.on(true); 
      } 
      read = dgStream1.read(buff); 
      f1ReadTotal += read > 0 ? read : 0; 
     } while (read > 0); 

     read = 0; 
     do { 
      if ((f2Length - f2ReadTotal) < (1024 * 128)) { 
       // last read 
       dgStream2.on(true); 
      } 
      read = dgStream2.read(buff); 
      f2ReadTotal += read > 0 ? read : 0; 
     } while (read > 0); 

     long runTime = System.nanoTime() - start; 
     if (Arrays.equals(dgStream1.getMessageDigest().digest(), dgStream2 
       .getMessageDigest().digest())) { 
      System.out.println("Files are identical. completed in " 
        + (runTime/1000000) + " ms. [" + runTime + " ns.]"); 
     } else { 
      System.out.println("Files are not identical. completed in " 
        + (runTime/1000000) + " ms. [" + runTime + " ns.]"); 
     } 

     fis1.close(); 
     fis2.close(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

주요 요점은, 그래서 마지막 읽기에 한 번을한다.

동의어 : 코드는 단지 아이디어 일뿐입니다. 실제 코드는 "마지막 읽기"에 특히주의를 기울여야하며 확실히 더 최적이 될 수 있습니다.