2011-01-07 3 views
2

일부 파일을 프로젝트의 다른 디렉토리로 이동하는 중입니다. 올바르게 이동되었는지 확인할 수 없다는 것을 제외하고는 훌륭하게 작동합니다.파일이 Java로 복사되었는지 확인하십시오.

사본의 길이가 원본과 동일하다는 것을 확인하고 원본을 삭제하고 싶습니다. 내 검증을하기 전에 두 FileStreams를 닫고 있지만 크기가 다르기 때문에 여전히 실패합니다. 아래는 스트림을 닫고 확인 및 삭제하는 코드입니다.

in.close(); 
out.close(); 

if (encCopyFile.exists() && encCopyFile.length() == encryptedFile.length()) 
    encryptedFile.delete(); 

이 전에 코드의 나머지는 스트림을 복사 할 백분율을 사용하고, 모든 잘 작동 그래서 정말 난 그냥 더 나은 검증 방법이 필요합니다.

+0

왜 예외를 발생시키지 않은 쓰기 작업이 어떻게 든 원본에 일치하지 않는 파일을 생성한다고 예상 하시겠습니까? –

+0

미친 일이 일어 났고 데이터 손실이 세계의 끝이 아니기 때문에 오히려 내 시계에서 발생하지 않을 것입니다. – Shaded

+0

어떻게 파일을 읽고 쓰고 있습니까? 이것이 바이너리 또는 텍스트 파일입니까? –

답변

2

복사 작업에 체크섬을 포함 할 수 있습니다. 대상 파일에서 체크섬을 수행하고 소스의 체크섬과 일치하는지 확인합니다.

+0

나는 최초의 발언이 나를 편집증 환자로 생각하고 있다고 생각한다. 나는 잘못된 문제를보고 있었고, 당신은 나를 먼저 불러 내고 대답을 얻을 수 있었다. 내 삭제가 작동하지 않는 이유를 알아 내기 위해 새 스레드를 열어야 할 수도 있습니다. – Shaded

4

확인할 수있는 멋진 방법 중 하나는 MD5 해시를 비교하는 것입니다. 파일 길이를 검사한다고해서 그것이 동일하다는 것은 아닙니다. md5 해시가 동일하다는 것을 의미하는 것은 아니지만 더 긴 프로세스 가긴하지만 길이를 확인하는 것보다 낫습니다.

public class Main { 

    public static void main(String[] args) throws NoSuchAlgorithmException, IOException { 
     System.out.println("Are identical: " + isIdentical("c:\\myfile.txt", "c:\\myfile2.txt")); 
    } 

    public static boolean isIdentical(String leftFile, String rightFile) throws IOException, NoSuchAlgorithmException { 
     return md5(leftFile).equals(md5(rightFile)); 
    } 

    private static String md5(String file) throws IOException, NoSuchAlgorithmException { 
     MessageDigest digest = MessageDigest.getInstance("MD5"); 
     File f = new File(file); 
     InputStream is = new FileInputStream(f); 
     byte[] buffer = new byte[8192]; 
     int read = 0; 
     try { 
      while ((read = is.read(buffer)) > 0) { 
       digest.update(buffer, 0, read); 
      } 
      byte[] md5sum = digest.digest(); 
      BigInteger bigInt = new BigInteger(1, md5sum); 
      String output = bigInt.toString(16); 
      return output; 
     } finally { 
      is.close(); 
     } 
    } 
} 
+0

'BigInteger bigInt = new BigInteger (1, md5sum); String output = bigInt.toString (16);은 다이제스트의 16 진수 문자열을 생성하는 흥미로운 방법입니다. –

+0

+1을 사용하면 더 정확한 방법을 알 수 있습니다. 감사! – Shaded

2

당신은 IO 공유지를 사용할 수 있습니다

org.apache.commons.io.FileUtils.contentEquals(File file1, File file2) 

하거나 검사 방법을 사용할 수 있습니다 스트림을 복사하는 동안 당신은 예외를 얻을 경우

org.apache.commons.io.FileUtils: 
static Checksum checksum(File file, Checksum checksum) //Computes the checksum of a file using the specified checksum object. 
static long checksumCRC32(File file) //Computes the checksum of a file using the CRC32 checksum routine. 
+1

불행히도 내 프로젝트에서 사용할 수있는 lib가 없으므로 작동하지 않습니다. – Shaded

3

, 당신은 확인해야합니다. close 메소드에 의해 던진 예외를 무시하지 않도록하십시오!

업데이트 : 당신이 FileOutputStream를 사용하는 경우, 당신은 또한 확실히 모든 것을 할 수 있습니다 귀하의 fileOutputStream을 닫기 전에 fileOutputStream.getFD().sync()를 호출하여 제대로 작성되었습니다.

물론 파일이 동일하다는 것을 확실하게 확인하려면 체크섬/다이제스트를 비교할 수 있지만 편집증적일 것 같습니다.

+0

체크섬을 사용하는 방법을 이해하는 것은 실제로 유용하지만 여전히 여기에 붙어 있습니다. 예외없이 복제 작업이 나쁜 결과를 가져 오는 것은 거의 없다고 생각합니다. 네트워크를 통해서조차도 이러한 프로토콜에 대한 인터페이스가 개발자에게 이런 종류의 일을 처리 할 것으로 기대합니다. –

+0

@yock : 예, NFS를 통해 파일을 쓸 때 IOException을 던지는 FileOutputStream.close() 메서드를 실제로 보았습니다. –

1

크기가 다른 경우 출력 스트림을 닫기 전에 플러시하지 않을 수도 있습니다.

어떤 파일이 더 큽니까? 각 파일의 크기는 얼마입니까? 실제로 두 파일을보고 다른 점을 확인 했습니까?

관련 문제