Here is an approach using Akka threads. This uses read-only memory and can process fragments of files as they are read.
See "IO Stream File" at the bottom of this page for more information. http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0-RC3/scala/stream-io.html
Start with a simple build.sbt file:
scalaVersion := "2.11.6" libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-stream-experimental" % "1.0-RC3" )
The interesting parts are Source , Flow and Sink . Source is a SynchronousFileSource that is read in a large file with a block size of 65536 . A ByteString of block size is emitted from Source and consumed by Flow , which computes the SHA256 hash for each fragment. Finally, Sink consumes the exit from Flow and prints arrays of bytes. You will want to convert them and summarize with fold to get the total amount.
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
BYTE ARRAYS!
> run [info] Running LargeFile [ B@3d0587a6 [ B@360cc296 [ B@7fbb2192 ...
Brian source share