Clojure 中大文件的 md5 哈希

时间:2021-03-07 14:04:45

标签: clojure md5

如何修改此代码以处理更大的文件(2 GB)?在 Java 中 - 使用小缓冲区和 update(),在 Clojure 中 - 如何?

(defn md5 [io-factory]
      (let [bytes'
            (with-open [xin (clojure.java.io/input-stream io-factory)
                        xout (java.io.ByteArrayOutputStream.)]
              (clojure.java.io/copy xin xout)
              (.toByteArray xout))
            algorithm (java.security.MessageDigest/getInstance "MD5")
            raw (.digest algorithm bytes')]
        (format "%032x" (BigInteger. 1 raw))))

; Execution error (OutOfMemoryError) at java.util.Arrays/copyOf (Arrays.java:3236).
; Java heap space

感谢您的回答。

2 个答案:

答案 0 :(得分:4)

您可以使用 DigestInputStream 来计算散列,而无需同时将所有字节保存到内存中,因为它会在您消耗源流中的字节时递增地计算散列。


(defn copy+md5 [source sink]
  (let [digest (MessageDigest/getInstance "MD5")]
    (with-open [input-stream  (io/input-stream source)
                digest-stream (DigestInputStream. input-stream digest)
                output-stream (io/output-stream sink)]
      (io/copy digest-stream output-stream))
    (format "%032x" (BigInteger. 1 (.digest digest)))))

如果您除了计算散列之外没有对源的内容做任何事情,您可以为接收器创建 use the /dev/null equivalent (OutputStream/nullOutputStream) 实例。

答案 1 :(得分:2)

clj-digest 使用小缓冲区来计算 MD5 和其他消息摘要。

相关问题