Java 为什么两次通用编解码器md5的结果不同

Java 为什么两次通用编解码器md5的结果不同,java,inputstream,md5,Java,Inputstream,Md5,当我使用apachecommoncodecmd5hex来获得inputstream的md5结果时,却得到了两次不同的结果。示例代码如下所示: public static void main(String[] args) { String data = "D:\\test.jpg"; File file = new File(data); InputStream is = null; try { is = new FileInputStream(fi

当我使用apachecommoncodecmd5hex来获得inputstream的md5结果时,却得到了两次不同的结果。示例代码如下所示:

public static void main(String[] args) {
    String data = "D:\\test.jpg";
    File file = new File(data);
    InputStream is = null;
    try {
        is = new FileInputStream(file);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    String digest = null, digest2 = null;
    try {
        System.out.println(is.hashCode());
        digest = DigestUtils.md5Hex(is);
        System.out.println(is.hashCode());

        digest2 = DigestUtils.md5Hex(is);
        System.out.println(is.hashCode());

    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println("Digest = " + digest);
    System.out.println("Digest2 = " + digest2);
}
结果是:

1888654590
1888654590
1888654590
Digest = 5cc6c20f0b3aa9b44fe952da20cc928e
Digest2 = d41d8cd98f00b204e9800998ecf8427e
谢谢你的回答

输入流只能遍历一次。第一个调用遍历它并返回输入文件的MD5。第二次调用md5hex时,InputStream指向文件的末尾,因此digest2是的MD5。

d41d8cd98f00b204e9800998ecf8427e是空字符串的MD5哈希

这是因为is是一个流,这意味着一旦您在DigestUtils.md5Hexis中读取了它,光标就位于流的末尾,没有更多的数据可读取,因此尝试读取任何内容都将返回0字节

我建议将流的内容读入字节[],并对其进行散列。
有关如何从InputStream中获取字节[],请参阅。

您不能在InputStream中向后移动。因此,调用两次:

DigestUtils.md5Hex(is);
不一样。更好地读入字节数组并使用:

public static String md5Hex(byte[] data)

我想,但我可能大错特错,因此这是一个评论,而不是一个答案,你不应该尝试散列流。流是一个数据源,您通常尝试对数据本身进行散列,而不是对数据的来源进行散列。因此,我认为您应该将文件中的所有数据流出来,并将结果散列一个字节[],可能是直接对文件进行散列。至于为什么散列是不同的,我猜这是因为流在您读取它时改变了它的状态,所以散列也改变了。@francesco是的!使用byte[]是更好的方式,谢谢。谢谢,太傻了,没有发现的md5值:,现在,我现在知道这个问题的原因了