PreCalculate File Stream Checksum

I am trying to provide output file integrity in case of disk space, network problems, or any exception that may occur during the streaming process to the file. Is there a way to pre-calculate the FileStream control string before writing to disk, and then check if the file is written correctly. for me it sounds a little pointless that the system checks the integrity of its own exported XML through checkSum, normalizing its work on the other end to check if the consumed file matches the file created by another system.

but this is a requirement that I have to implement.

its stream, which I write as a file:

 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();
+3
source share
4

:

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

}
+1

, , . , .

, , - .

+3

- . - , , .

- , .

- ( ().getFreeSpace())

MD5 .

+3

MD5,

MD5 .

. fooobar.com/questions/11687/...

Then, after saving the file, you can generate md5 again and compare

UPDATE - here is my more detailed idea for this. I assume that you just want to compute MD5 without having to insert the entire byte [] into memory. In this case, I think you have 2 options

  • count MD5 on the fly when you save, then check md5 again after saving (if you are using Linux, you can just use md5sum)
  • calculate MD5 in the first pass, and then save the file for the second pass.

eg

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


    }
}

returns

410859520
dda81aea75a83b1489662c6bcd0677e4
1413 millis

and then

[leoks@home ~]$ md5sum /home/leoks/Downloads/VirtualBox-4.3.0.tar
dda81aea75a83b1489662c6bcd0677e4  /home/leoks/Downloads/VirtualBox-4.3.0.tar
[leoks@home ~]$ 
+1
source

All Articles