23.07.2013 Views

Java IO.pdf - Nguyen Dang Binh

Java IO.pdf - Nguyen Dang Binh

Java IO.pdf - Nguyen Dang Binh

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

}<br />

}<br />

catch (Exception e) {System.err.println(e);}<br />

public static void copyFileWithDigest(InputStream in, OutputStream out)<br />

throws <strong>IO</strong>Exception, NoSuchAlgorithmException {<br />

}<br />

MessageDigest sha = MessageDigest.getInstance("SHA");<br />

DigestOutputStream dout = new DigestOutputStream(out, sha);<br />

byte[] data = new byte[128];<br />

while (true) {<br />

int bytesRead = in.read(data);<br />

if (bytesRead < 0) break;<br />

dout.write(data, 0, bytesRead);<br />

}<br />

dout.flush();<br />

byte[] result = dout.getMessageDigest().digest();<br />

for (int i = 0; i < result.length; i++) {<br />

System.out.print(result[i] + " ");<br />

}<br />

System.out.println();<br />

A sample run looks like this:<br />

% java FileDigest http://www.oreilly.com/ oreilly.html<br />

10 -10 103 -27 -110 3 -2 -115 8 -112 13 19 25 76 -120 31 51 116 -94 -58<br />

<strong>Java</strong> I/O<br />

To be perfectly honest, I'm not sure if DigestOutputStream is all that useful. You still need<br />

to construct the MessageDigest object, pass it to the DigestOutputStream() constructor,<br />

retrieve the MessageDigest object from the output stream, invoke its digest() method, and<br />

retrieve the digest data from that object. The only real reason I can think of to use<br />

DigestOutputStream would be if you needed a digest in the middle of a chain of filter<br />

streams. For instance, you could write data onto a data output stream chained to a gzip output<br />

stream chained to a file output stream. When you had finished writing the data onto the data<br />

output stream, you could calculate the digest and write that directly onto the file output<br />

stream. When the data was read back in, you could use a digest input stream chained to a data<br />

input stream to check that the file had not been corrupted in the meantime. If the digest<br />

calculated by the digest input stream matched the digest stored in the file, you'd know the data<br />

was OK.<br />

I would prefer the DigestOutputStream to completely hide the MessageDigest object. You<br />

could pass the name of the digest algorithm to the constructor rather than an actual<br />

MessageDigest object. The digest would only be made available after the stream was closed,<br />

and then only through its data, not through the actual object. Example 10.4 demonstrates how<br />

such a class might be implemented.<br />

Example 10.4. EasyDigestOutputStream<br />

package com.macfaq.security;<br />

import java.io.*;<br />

import java.security.*;<br />

207

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!