2014-02-05 2 views
3

공간 부족, 네트워크 문제 또는 파일 프로세스에 스트리밍 중 발생할 수있는 anyException이 발생한 디스크의 경우 파일의 무결성을 보장하려고합니다. 에는 디스크에 쓰기 전에 FileStream checkSum을 미리 계산 한 다음 파일이 올바르게 작성되었는지 확인하는 방법이 있습니다. 시스템이 checkSum을 통해 자체 내 보낸 XML의 무결성을 확인한다는 사실이 조금 비 효과적이라고 생각합니다. 일반적으로 소비 된 파일이 다른 시스템에서 생성 된 파일에 맞는지 확인하기 위해 상대방의 작업입니다.preCalculate file stream checksum

하지만 구현해야하는 요구 사항입니다.

String xmlTransfer =""; 
    File testFile = new File("testFile.xml"); 
    InputStream in = new ByteArrayInputStream(xmlTransfer.getBytes("utf-8")); 
    FileOutputStream out = new FileOutputStream(testFile) 
    byte[] buffer = new byte[2048]; 
       int bytesRead; 
       while ((bytesRead = in.read(buffer)) != -1) { 
        out.write(buffer, 0, bytesRead); 
       } 
       out.close(); 
       in.close(); 
+0

파일 스트림을 읽는 동안 MD5를 계산하고 저장 후 다시 확인하는 방법은 무엇입니까? 이런 식으로 http://stackoverflow.com/questions/304268/getting-a-files-md5-checksum-in-java – Leo

+0

MD5를 계산하는 동안 문제가 발생하면 결과 파일의 내용을 알 수 없습니다. 디스크에 기록 된 내용이 유효한지 여부. – Genjuro

+0

MD5를 계산하는 데 문제가 있으면 파일을 다시 작성해야한다고 가정합니다. (최대 재시도 횟수를 잊지 말것) – Leo

답변

1

이 시도 :

import java.io.BufferedReader; 
import java.io.BufferedWriter; 
import java.io.ByteArrayInputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.FileWriter; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.OutputStream; 
import java.security.MessageDigest; 


public class CheckSumFileTest 
{ 

    private File buildChecksumFile(File fileToCheck, String filePrefix, String checksumAlgorithm) throws Exception 
    { 
     String checksum = null; 
     File checksumFile = null; 
     String tempDir = System.getProperty("java.io.tmpdir"); 
     try { 
      checksumFile = new File(tempDir, filePrefix+"."+ checksumAlgorithm.toLowerCase()); 
      checksumFile.createNewFile(); 
      checksumFile.deleteOnExit(); 
     } catch (Exception e1) { 
      e1.printStackTrace(); 
      throw e1; 
     } 
     FileWriter fw = null; 
     try { 
      checksum = checkSum(fileToCheck,checksumAlgorithm); 
      fw = new FileWriter(checksumFile); 
      fw.write(checksum); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      throw e; 
     } 
     finally 
     { 
      if(fw !=null) 
       fw.close(); 
     } 

     return checksumFile; 
    } 

    private static String checkSum(File file, String checksumAlgorithm) throws Exception 
    { 
     MessageDigest digest = MessageDigest.getInstance(checksumAlgorithm); 

     InputStream input = null; 
     StringBuffer sb = new StringBuffer(); 
     try{ 
      input = new FileInputStream(file); 
      byte[] buffer = new byte[8192]; 
      do { 
       int read = input.read(buffer); 
       if(read <= 0) 
        break; 
       digest.update(buffer, 0, read); 
      } while(true); 
      byte[] sum = digest.digest(); 

      for (int i = 0; i < sum.length; i++) { 
       sb.append(Integer.toString((sum[i] & 0xff) + 0x100, 16).substring(1)); 
      } 

     }catch(IOException io) 
     { 

     }finally{ 
      if(input != null) 
       input.close(); 
     } 

     return sb.toString(); 
    } 

    private static String checkSumInStream(InputStream stream, String checksumAlgorithm) throws Exception 
    { 
     MessageDigest digest = MessageDigest.getInstance(checksumAlgorithm); 

     InputStream input = null; 
     StringBuffer sb = new StringBuffer(); 
     try{ 
      input = stream; 
      byte[] buffer = new byte[8192]; 
      do { 
       int read = input.read(buffer); 
       if(read <= 0) 
        break; 
       digest.update(buffer, 0, read); 
      } while(true); 
      byte[] sum = digest.digest(); 

      for (int i = 0; i < sum.length; i++) { 
       sb.append(Integer.toString((sum[i] & 0xff) + 0x100, 16).substring(1)); 
      } 

     }catch(IOException io) 
     { 

     }finally{ 
      if(input != null) 
       input.close(); 
     } 

     return sb.toString(); 
    } 

    private boolean checkIntegrity(String targetFileName, String checksumFileName, String checksumAlgorithm) throws Exception 
    { 
     FileInputStream stream = null; 
     BufferedReader br = null; 
     InputStreamReader ipsr = null; 
     File checksumFile = null; 
     String checksumString=""; 
     File targetFile = new File(targetFileName); 
     try{ 
      checksumFile = new File(checksumFileName); 
      stream = new FileInputStream(checksumFile); 
      ipsr = new InputStreamReader(stream); 
      br = new BufferedReader(ipsr); 

      //In checksum file : only one line to read 
      checksumString = br.readLine(); 

     }finally 
     { 
      if(br != null) 
       br.close(); 
      if(ipsr != null) 
       ipsr.close(); 
      if(stream != null) 
       stream.close(); 
     } 


     if(checksumString.equals(checkSum(targetFile,checksumAlgorithm))) 
     { 
      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 



    /** 
    * @param args 
    */ 
    public static void main(String[] args) 
    { 
     String str = "Amine"; 
     InputStream stream = new ByteArrayInputStream(str.getBytes()); 
     //step1 
     try { 
      System.out.println(checkSumInStream(stream,"MD5")); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     //step2 
     File file = new File("c:/test.txt"); 

     // if file doesnt exists, then create it 
     if (!file.exists()) { 
      try { 
       file.createNewFile(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     FileWriter fw; 
     BufferedWriter bw; 

     try { 
      fw = new FileWriter(file.getAbsoluteFile()); 
      bw = new BufferedWriter(fw); 
      bw.write(str); 
      bw.close(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     try { 
      System.out.println(checkSum(file, "MD5")); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     System.out.println("Done"); 
    } 

} 
3

아니, 당신은 사전에 스트림에서 올 것이다 얼마나 많은 데이터를 알아낼 수 없습니다 :

그녀는 내가 파일로 쓰기 스트림입니다. 단순히 스트림이 작동하는 방식이 아닙니다.

코드의 양쪽 끝을 작성하는 경우 수행 할 수있는 작업은 먼저 파일 끝에있는 파일 크기를 계산하여 파일 내용 자체를 보내기 전에 보내는 것입니다.

3

가장 좋은 방법은 예외를 잡는 것입니다. 문제가 발생하면 예외가 발생하고이 경우 부분적으로 작성된 파일을 제거 할 수 있습니다.

두 번째 방법은 파일 시스템에 기록하기 전에 메모리 내 스트림을 갖는 것입니다. 그러나 메모리를 소비합니다.

세 번째 방법은 대상 디스크 용량을 확인하는 것입니다 (새로운 파일 (경로) .getFreeSpace을())

MD5 검사가 문제의 안부 나에게 너무 느린 소리.

+0

솔루션은 어떻게 든 그것은 다른 프로세스에 의해 사용된다는 사실 때문에 파일을 삭제할 수 없다는 것입니다. 이상한 문제입니다. 나는 모든 스트림이 제대로 닫혔는지 확인했습니다. – Genjuro

1

당신은 크기

당신이 스트림을 읽는 동안 당신은 당신의 MD5를 계산할 수를 제출하지, MD5로 확인해야합니다.

파일을 저장 한 후, 당신은 다시 MD5를 생성하고

UPDATE를 비교할 수 있습니다, 그리고

https://stackoverflow.com/a/304350/3230038을 참조하십시오 - 여기에 대한 내 더 자세한 생각입니다. 나는 전체 byte []를 메모리에 가져 오지 않고 MD5를 계산하기를 원한다고 가정하고 있습니다. 이 경우, 나는 (당신이 리눅스에 있다면 당신은 그냥 md5sum이 사용할 수 있습니다) 다시 MD5를 확인, 당신은 저장 한 후 다음 저장하고 당신이, 즉석에서이 옵션

  1. 계산 MD5를 생각
  2. 첫 번째 패스에서 MD5를 계산 한 다음 두 번째 패스에서 파일을 저장합니다.예를 들어

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.security.DigestInputStream; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 

import org.apache.commons.io.IOUtils; 
import org.apache.commons.io.output.NullOutputStream; 


public class MD5OnTheFly { 

    /** 
    * @param args 
    * @throws NoSuchAlgorithmException 
    * @throws IOException 
    */ 
    public static void main(String[] args) throws NoSuchAlgorithmException, IOException { 

     long ini = System.currentTimeMillis(); 

     File file = new File("/home/leoks/Downloads/VirtualBox-4.3.0.tar"); 

     System.out.println("size:"+file.length()); 

     InputStream is = new FileInputStream(file); 

     MessageDigest md = MessageDigest.getInstance("MD5"); 

     DigestInputStream dis = new DigestInputStream(is, md); 

     IOUtils.copy(dis, new NullOutputStream()); 

     byte[] digest = md.digest(); 

     StringBuffer hexString = new StringBuffer(); 
     for (int i = 0; i < digest.length; i++) { 
      String hex = Integer.toHexString(0xff & digest[i]); 
      if (hex.length() == 1) 
       hexString.append('0'); 
      hexString.append(hex); 
     } 

     System.out.println(hexString); 

     long end = System.currentTimeMillis(); 
     System.out.println(end-ini+" millis"); 


    } 
} 

반환

410859520 
dda81aea75a83b1489662c6bcd0677e4 
1413 millis 

다음

[[email protected] ~]$ md5sum /home/leoks/Downloads/VirtualBox-4.3.0.tar 
dda81aea75a83b1489662c6bcd0677e4 /home/leoks/Downloads/VirtualBox-4.3.0.tar 
[[email protected] ~]$