4

所以我想知道如何使用 scalaz-stream 来生成使用 java.security.MessageDigest 的文件摘要?

我想使用一个恒定的内存缓冲区大小(例如 4KB)来做到这一点。我想我知道如何开始阅读文件,但我很难理解如何:

1) 调用digest.update(buf)每 4KB,这实际上是对 Java MessageDigest 实例的副作用,我猜这应该发生在 scalaz-stream 框架内。

2) 最后调用digest.digest()以从 scalaz-stream 框架内接收计算出的摘要如何?

我想我明白如何开始:

import scalaz.stream._
import java.security.MessageDigest

val f = "/a/b/myfile.bin"
val bufSize = 4096

val digest = MessageDigest.getInstance("SHA-256")

Process.constant(bufSize).toSource
  .through(io.fileChunkR(f, bufSize))

但后来我被困住了!请问有什么提示吗?我想它必须也可以将摘要对象的创建,更新,检索(实际摘要计算)和销毁包装在scalaz-stream Sink或其他东西中,然后调用.to()传递该Sink?抱歉,如果我使用了错误的术语,我对使用 scalaz-stream 完全陌生。我已经通过了一些示例,但仍在苦苦挣扎。

4

2 回答 2

3

由于版本 0.4 scalaz-stream 包含计算摘要的过程。它们在hash模块中可用并java.security.MessageDigest在引擎盖下使用。这是一个如何使用它们的最小示例:

import scalaz.concurrent.Task
import scalaz.stream._

object Sha1Sum extends App {
  val fileName = "testdata/celsius.txt"
  val bufferSize = 4096

  val sha1sum: Task[Option[String]] =
    Process.constant(bufferSize)
      .toSource
      .through(io.fileChunkR(fileName, bufferSize))
      .pipe(hash.sha1)
      .map(sum => s"${sum.toHex}  $fileName")
      .runLast

  sha1sum.run.foreach(println)
}

和调用update()digest()包含在hash.sha1 Process1.

于 2014-08-20T18:54:17.220 回答
0

所以我有一些工作,但它可能会得到改进:

import java.io._
import java.security.MessageDigest
import resource._
import scodec.bits.ByteVector
import scalaz._, Scalaz._
import scalaz.concurrent.Task
import scalaz.stream._
import scalaz.stream.io._

val f = "/a/b/myfile.bin"
val bufSize = 4096

val md = MessageDigest.getInstance("SHA-256")

def _digestResource(md: => MessageDigest): Sink[Task,ByteVector] =
      resource(Task.delay(md))(md => Task.delay(()))(
        md => Task.now((bytes: ByteVector) => Task.delay(md.update(bytes.toArray))))

Process.constant(4096).toSource
    .through(fileChunkR(f.getAbsolutePath, 4096))
    .to(_digestResource(md))
    .run
    .run

md.digest()

但是,在我看来,应该有一种更清洁的方法来做到这一点,通过移动MessageDigestscalaz-stream 内容内部的创建并最终.run生成md.digest().

欢迎更好的答案...

于 2014-08-20T08:50:56.817 回答