3

说,在一个动作中我有:

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)

如何关闭读者/流?

4

2 回答 2

3

有一个onDoneEnumerating回调函数finally(无论是否Enumerator失败,都会被调用)。您可以在那里关闭流。

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.
    }
}
于 2014-11-15T15:13:19.860 回答
2

提供的 IO 工具为Enumerator您提供了这种开箱即用的资源管理 - 例如,如果您使用 创建枚举fromStream器,则保证在运行后关闭流(即使您只读取一行等)。

因此,例如,您可以编写以下内容:

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)

遗憾的是,该库没有提供linesFromStream开箱即用的功能,但我个人仍然更喜欢使用fromStream手动拆分等,而不是使用迭代器并提供我自己的资源管理。

于 2014-11-15T15:46:57.050 回答