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