gpt4 book ai didi

scala - 在连续 block 中读取非常大的文件 (~ 1 TB)

转载 作者:行者123 更新时间:2023-12-04 12:19:52 24 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





How do I read a large CSV file with Scala Stream class?

(3 个回答)


6年前关闭。




我需要在 Scala 中读取一个大文件并以 k 位块(k 通常为 65536)进行处理。作为一个简单的例子(但不是我想要的):

文件块是 (f1, f2, ... fk) .

我想计算 SHA256(f1)+SHA256(f2)+...+ SHA256(fk)
这样的计算可以仅使用常量存储和当前块而无需其他块即可增量完成。

读取文件的最佳方法是什么? (也许使用延续的东西?)

编辑:链接的问题可以解决问题,但并非总是如此,因为我正在查看的文件包含二进制数据。

最佳答案

这是使用 Akka Streams 的一种方法。这使用常量内存,并且可以在读取文件块时对其进行处理。

有关详细信息,请参阅本页底部的“流文件 IO”。 http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0-RC3/scala/stream-io.html

从一个简单的 build.sbt 开始文件:

scalaVersion := "2.11.6"

libraryDependencies ++= Seq(
"com.typesafe.akka" %% "akka-stream-experimental" % "1.0-RC3"
)

有趣的部分是 Source , Flow , 和 Sink . SourceSynchronousFileSource读取块大小为 65536 的大文件.一个 ByteString块大小是从 Source 发出的并被 Flow 消耗它为每个块计算一个 SHA256 哈希值。最后, Sink消耗来自 Flow 的输出并打印出字节数组。您需要转换这些并使用 fold 对它们求和。得到一个总和。
import akka.stream.io._
import java.io.File
import scala.concurrent.Future
import akka.stream.scaladsl._
import akka.actor.ActorSystem
import akka.stream.ActorFlowMaterializer
import java.security.MessageDigest

object LargeFile extends App{
implicit val system = ActorSystem("Sys")
import system.dispatcher
implicit val materializer = ActorFlowMaterializer()

val file = new File("<path to large file>")

val fileSource = SynchronousFileSource(file, 65536)

val shaFlow = fileSource.map(chunk => sha256(chunk.toString))

shaFlow.to(Sink.foreach(println(_))).run//TODO - Convert the byte[] and sum them using fold

def sha256(s: String) = {
val messageDigest = MessageDigest.getInstance("SHA-256")
messageDigest.digest(s.getBytes("UTF-8"))
}
}

字节数组!
> run
[info] Running LargeFile
[B@3d0587a6
[B@360cc296
[B@7fbb2192
...

关于scala - 在连续 block 中读取非常大的文件 (~ 1 TB),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30754285/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com