Java:如何在正在保存的流上即时计算 sha1 摘要?

标签 java stream digest

我有一个用 Java 编写的 servlet,它接受需要保存在 MongoDb/GridFS 中的多部分形式的发布文件。我已经有了为此工作的代码。

这是一个代码片段,展示了如何使用 org.apache.commons.fileupload 包完成它。它几乎不消耗内存,因为它不会在内存中保留太多数据。

        ServletFileUpload upload = new ServletFileUpload();
        FileItemIterator iter = upload.getItemIterator(req);
        while (iter.hasNext()) {
            FileItemStream item = iter.next();
            String name = item.getFieldName();
            InputStream stream = item.openStream();
            if (item.isFormField()) {
                toProcess.put(name, Streams.asString(stream));
            } else {
                String fileName = item.getName();
                String contentType = item.getHeaders().getHeader("Content-Type");
                GridFSUploadOptions options = new GridFSUploadOptions()
                        // .chunkSizeBytes(358400)
                        .metadata(new Document("content_type", contentType));
                ObjectId fileId = gridFSFilesBucket.uploadFromStream(fileName, stream, options);
                fileIds.add(fileId);
                fileNames.add(fileName);
            }

我还需要计算所有文件的 sha1 哈希值。 Apache digestutils 可以用于此。它有一个可以在流上计算 sha1 的方法:

https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/digest/DigestUtils.html#sha1-java.io.InputStream-

我的问题是这个方法完全消耗了流。我需要将输入流分成两部分。将一部分送入 SHA-1 计算,将另一部分送入 GridFS 存储桶。

我该怎么做?我正在考虑创建我自己的“管道”,它有一个输入和一个输出流,转发所有数据但动态更新摘要。

我只是不知道如何开始编写这样的管道。

最佳答案

您可以使用 Java API class DigestInputStream

正如 Javadoc 所解释的那样,

A transparent stream that updates the associated message digest using the bits going through the stream.

To complete the message digest computation, call one of the digest methods on the associated message digest after your calls to one of this digest input stream's read methods.

在您的代码中,您可以这样做:

InputStream stream = item.openStream();
MessageDigest digest = MessageDigest.getInstance("SHA-256");
stream = new DigestInputStream(stream, digest);

最后你可以得到摘要:

byte[] hash = digest.digest();

关于Java:如何在正在保存的流上即时计算 sha1 摘要?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52160214/

相关文章:

python - 将 Netcat 流写入带有附加文本的文件

java - Apache 耶拿 - java.lang.UnsupportedClassVersionError : com/hp/hpl/jena/rdf/model/ModelFactory

java - 如何向方法的参数添加 JSR 303 验证

java - 使用字符串和数组列表

java - 收集所有发出的 SQL 的最简单方法

ruby-on-rails - Rails 编译带有和不带有 md5 哈希值的 Assets ,为什么?

r - 为 R 中的字符串创建唯一的、人类可读的标识符(哈希?)

java - 我们如何在 Android 应用程序中创建 Kafka 生产者?

java - ObjectInputStream 不适用于套接字

c - 使用 C 程序验证用私钥签名的摘要