如何修改此代码以处理更大的文件(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
感谢您的回答。
答案 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 和其他消息摘要。