What is the \"proper\" of writing the standard read-while loop in Scala? By proper I mean written in a Scala-like way as opposed to a Java-like way.
Here is the code I
What Rex Kerr suggests in his comment is the following:
val md = MessageDigest.getInstance("MD5")
val input = new FileInputStream("foo.txt")
val buffer = new Array[ Byte ]( 1024 )
Stream.continually(input.read(buffer))
.takeWhile(_ != -1)
.foreach(md.update(buffer, 0, _))
md.digest
The key is the Stream.continually
. It gets an expression which is evaluated continually, creating an infinite Stream
of the evaluated expression. The takeWhile
is the translation from the while
-condition. The foreach
is the body of the while
-loop.
What about a curried function? You 11 lines of Scala code become:
val md = MessageDigest.getInstance(hashInfo.algorithm)
val input = new FileInputStream("file")
iterateStream(input){ (data, length) =>
md.update(data, 0, length)
}
md.digest
The iterateStream
function on line 3, which you could add to a library is:
def iterateStream(input: InputStream)(f: (Array[Byte], Int) => Unit){
val buffer = new Array[Byte](512)
var curr = input.read(buffer)
while(curr != -1){
f(buffer, curr)
curr = input.read(buffer)
}
}
The ugly duplicated code (where the input is read) ends up in the library, well tested and hidden away from the programmer. I feel that the first block of code is less complex than the Iterator.continually
solution.
Based on Rex's post that he mentioned:
Stream.continually(input.read(buffer)).takeWhile(_ != -1).foreach(md.update(buffer, 0, _))
You should replace the var readLen + while {...} lines with it, it produces the same result.
As Rex mentioned, it works with scala 2.8.