Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to close enumerated file?

Say, in an action I have:

val linesEnu = {
    val is = new java.io.FileInputStream(path)
    val isr = new java.io.InputStreamReader(is, "UTF-8")
    val br = new java.io.BufferedReader(isr)
    import scala.collection.JavaConversions._
    val rows: scala.collection.Iterator[String] = br.lines.iterator
    Enumerator.enumerate(rows)
}

Ok.feed(linesEnu).as(HTML)

How to close readers/streams?

like image 669
Andrew Gaydenko Avatar asked Nov 19 '25 03:11

Andrew Gaydenko


2 Answers

There is a onDoneEnumerating callback that functions like finally (will always be called whether or not the Enumerator fails). You can close the streams there.

val linesEnu = {
    val is = new java.io.FileInputStream(path)
    val isr = new java.io.InputStreamReader(is, "UTF-8")
    val br = new java.io.BufferedReader(isr)
    import scala.collection.JavaConversions._
    val rows: scala.collection.Iterator[String] = br.lines.iterator
    Enumerator.enumerate(rows).onDoneEnumerating {
        is.close()
        // ... Anything else you want to execute when the Enumerator finishes.
    }
}
like image 88
Michael Zajac Avatar answered Nov 20 '25 16:11

Michael Zajac


The IO tools provided by Enumerator give you this kind of resource management out of the box—e.g. if you create an enumerator with fromStream, the stream is guaranteed to get closed after running (even if you only read a single line, etc.).

So for example you could write the following:

import play.api.libs.iteratee._

val splitByNl = Enumeratee.grouped(
  Traversable.splitOnceAt[Array[Byte], Byte](_ != '\n'.toByte) &>>
  Iteratee.consume()
) compose Enumeratee.map(new String(_, "UTF-8"))

def fileLines(path: String): Enumerator[String] =
  Enumerator.fromStream(new java.io.FileInputStream(path)).through(splitByNl)

It's a shame that the library doesn't provide a linesFromStream out of the box, but I personally would still prefer to use fromStream with hand-rolled splitting, etc. over using an iterator and providing my own resource management.

like image 43
Travis Brown Avatar answered Nov 20 '25 17:11

Travis Brown



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!