java - 如何计算Inputstream的MD5

查看:369
本文介绍了java - 如何计算Inputstream的MD5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

问题如下:

我首先通过文件上传取得了一个inputstream,这时如果我直接对这个流进行MD5的话,之后便无法保存文件了,应该是流已经被读取过无法再次读取。

MD5计算用的是apache commons-codec:
String md5 = DigestUtils.md5Hex(inputStream); // 之后无法保存文件
FileUtils.copyInputStreamToFile(inputStream, file); // 无法保存文件

请问有什么办法既能够得到MD5又能够保存文件呢,在只用inputstream的情况下,不要把流读入一个byte数组,我并不知道它多大。

解决方案

首先,最简单的方式就是把你的两行代码结合起来,先保存文件,再读取文件流计算MD5:

public static String copyInputStreamToFileAndGetMd5Hex(InputStream inputStream, File file) throws IOException {
    FileUtils.copyInputStreamToFile(inputStream, file);
    return DigestUtils.md5Hex(new FileInputStream(file));
}

当然这样做要对同一个流读取两次,显得不够低碳环保。

此时可以看下DigestUtils源码,追其根溯其源可以看到:

    public static MessageDigest updateDigest(final MessageDigest digest, final InputStream data) throws IOException {
        final byte[] buffer = new byte[STREAM_BUFFER_LENGTH];
        int read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);

        while (read > -1) {
            digest.update(buffer, 0, read);
            read = data.read(buffer, 0, STREAM_BUFFER_LENGTH);
        }

        return digest;
    }

也不是多高级的技术,就是把整个InputStream拆成长度1024的字节数组逐个MD5。

再看看FileUtils.copyInputStreamToFile源码的追根溯源实现:


    public static long copyLarge(InputStream input, OutputStream output, byte[] buffer) throws IOException {
        long count;
        int n;
        for(count = 0L; -1 != (n = input.read(buffer)); count += (long)n) {
            output.write(buffer, 0, n);
        }

        return count;
    }

同样也是讲InputStream拆成4096的字节数组,逐个写到目标文件中。

那么,两者结合起来代码也就好写了:

    public static String copyInputStreamToFileAndGetMd5Hex(InputStream inputStream, File file) throws IOException {

        MessageDigest digest = DigestUtils.getMd5Digest();

        FileOutputStream outputStream = null;

        try {
            outputStream = new FileOutputStream(file);
            byte[] buffer = new byte[2048];
            int read = inputStream.read(buffer);
            while (read > -1) {
                // 计算MD5,顺便写到文件
                digest.update(buffer, 0, read);
                outputStream.write(buffer, 0, read);

                read = inputStream.read(buffer);
            }
        } finally {
            IOUtils.closeQuietly(outputStream);
        }

        return Hex.encodeHexString(digest.digest());
    }

这篇关于java - 如何计算Inputstream的MD5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆