Search code examples
javahashfileinputstreamdigest

Why can't I use FileInputStream to feed MessageDigest object?


Why must I use DigestInputStream and not FileInputStream to get a digest of an file?

I have written a program that reads ints from FileInputStream, converts them to bytes and passes them to update method of MessageDigest object. But I have a suspicion that it doesn't work properly, because it calculates a digest of a very large file instanlty. Why doesn't it work?

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class DigestDemo {

    public static byte[] getSha1(String file) {
        FileInputStream fis = null;
        MessageDigest md = null;

        try {
            fis = new FileInputStream(file);
        } catch(FileNotFoundException exc) {
            System.out.println(exc);
        }

        try {
            md = MessageDigest.getInstance("SHA-1");
        } catch (NoSuchAlgorithmException exc) {
            System.out.println(exc);
        }

        byte b = 0;
        do {

            try {
                b = (byte) fis.read();
            } catch (IOException e) {
                System.out.println(e);
            }

            if (b != -1)
                md.update(b);

        } while(b != -1);

        return md.digest();

    }

    public static void writeBytes(byte[] a) {
        for (byte b : a) {
            System.out.printf("%x", b);
        }
    }

    public static void main(String[] args) {

        String file = "C:\\Users\\Mike\\Desktop\\test.txt";
        byte[] digest = getSha1(file);
        writeBytes(digest);

    }

}

Solution

  • You need to change the type of b to int,, and you need to call MessageDigest.doFinal() at the end of the file, but this is horrifically inefficient. Try reading and updating from a byte array.

    There's too much try-catching in this code. Reduce it to one try and two catches, outside the loop.