3.2.5 DigestOutputStream
与DigestInputStream类相对应,DigestOutputStream类继承了FilterOutputStream类,可以通过写入输出流的方式完成摘要更新,因此我们称它为消息摘要输出流,在指定的写操作方法内部完成MessageDigest类的update()方法。
//提供一个输出流,针对所有通过该流的数据计算出相应的消息摘要。
public class DigestOutputStream
extends FilterOutputStream
❑方法详述
可以通过以下方法实例化对象:
/使用指定的OutputStream和MessageDigest创建一个DigestOutputStream实例。/
public DigestOutputStream(OutputStream stream, MessageDigest digest)
以下方法与DigestInputStream类相同:
//将指定的MessageDigest与此流相关联。
public void setMessageDigest(MessageDigest digest)
//返回与此流关联的MessageDigest。
public MessageDigest getMessageDigest()
当通过下述方法关闭摘要功能后,DigestOutputStream就变成了一般的输出流:
//开启或关闭摘要功能。
public void on(boolean on)
请注意要使用下述方法更新摘要信息时,一定要确保DigestOutputStream开启摘要功能:
/使用指定的字节更新消息摘要(如果开启了摘要功能),并将字节写入输出流(不管是否开启了摘要功能)。/
public void write(int b)
/使用指定的子数组更新消息摘要(如果开启了摘要功能),并将子数组写入输出流(不管是否开启了摘要功能)。/
public void write(byte[]b, int off, int len)
上述方法将调用MessageDigest类的update()方法完成摘要更新,在此之后可以通过getMessageDigest()方法获得MessageDigest对象,并执行MessageDigest类的digest()方法完成摘要操作。
摘要DigestOutputStream类的相关源码如代码清单3-5所示。
代码清单3-5 DigestOutputStream类写操作部分源代码
public void write(int b)throws IOException{
if(on){
digest.update((byte)b);
}
out.write(b);
}
public void write(byte[]b, int off, int len)throws IOException{
if(on){
digest.update(b, off, len);
}
out.write(b, off, len);
}
除上述方法外,通常还用到以下方法:
//打印此摘要输出流及其关联的消息摘要对象的字符串表示形式。
public String toString()
❑实现示例
我们可以通过如代码清单3-6所示的方式使用该消息摘要输出流。
代码清单3-6 MD5算法摘要输出流处理
//待做消息摘要的原始信息。
byte[]input="md5".getBytes();
//初始化MessageDigest,将使用MD5算法。
MessageDigest md=MessageDigest.getInstance("MD5");
//初始化DigestOutputStream。
DigestOutputStream dos=new DigestOutputStream(new ByteArrayOutputStream(),md);
//流输出
dos.write(input,0,input.length);
//获得摘要信息
byte[]output=dos.getMessageDigest().digest();
//清空流
dos.flush();
//关闭流
dos.close();