代码之家  ›  专栏  ›  技术社区  ›  nagylzs

Java:如何在正在保存的流中实时计算Sa1摘要?

  •  0
  • nagylzs  · 技术社区  · 7 年前

    我有一个用Java编写的servlet,它接受需要保存在MunGDB/GRIDFS中的MultPoT表单发布的文件。我已经有了这个代码。

    下面是一个代码片段,展示了如何使用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桶。

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

    我只是不知道怎么开始写这样的管道。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Erwin Bolwidt    7 年前

    你可以使用 Java API class DigestInputStream

    正如JavaDoc解释的那样,

    一个透明流,它使用 流过小溪的钻头。

    完成消息摘要 计算,调用关联消息的摘要方法之一 在调用此摘要输入流的某个 方法。

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

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

    最后,您可以通过以下方式获得摘要:

    byte[] hash = digest.digest();