问题如下:
我首先通过文件上传取得了一个inputstream,这时如果我直接对这个流进行MD5的话,之后便无法保存文件了,应该是流已经被读取过无法再次读取。
MD5计算用的是apache commons-codec:
String md5 = DigestUtils.md5Hex(inputStream); // 之后无法保存文件
FileUtils.copyInputStreamToFile(inputStream, file); // 无法保存文件
请问有什么办法既能够得到MD5又能够保存文件呢,在只用inputstream的情况下,不要把流读入一个byte数组,我并不知道它多大。
进行md5计算过后的inputStream他的指针已经指到末尾了
所以在进行保存时就没有数据可以保存了
使用inputStream的mark和reset可以将指针指到末尾后再回到mark的位置 但需要先将inputStream包装成BufferedInputStream类型
有人在SO上问了这个问题:
http://stackoverflow.com/ques...
思路就是用ByteArrayOutputStream
先把inputstream的内容放到byte[]数组里,读的时候用ByteArrayInputStream
读取。
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;
while ((n = myInputStream.read(buf)) >= 0)
baos.write(buf, 0, n);
byte[] content = baos.toByteArray();
InputStream is1 = new ByteArrayInputStream(content);
... use is1 ...
InputStream is2 = new ByteArrayInputStream(content);
... use is2 ...
inputstream
只能读取一次吧,你先把文件保存下来,在打开这个文件的流获取md5
吧。
首先,最简单的方式就是把你的两行代码结合起来,先保存文件,再读取文件流计算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()); }