【发布时间】:2014-09-18 12:19:07
【问题描述】:
假设我正在阅读InputStream。
我通常会怎么做:
val inputStream = ...
try {
doStuff(inputStream)
} finally {
inputStream.close()
}
无论doStuff是否抛出异常,我们都会关闭InputStream。
我将如何使用迭代器:
val inputStream ...
Enumerator.fromStream(inputStream)(Iteratee.foreach(doStuff))
InputStream 是否会被关闭(即使doStuff 抛出异常)?
一个小测试:
val inputStream = new InputStream() { // returns 10, 9, ... 0, -1
private var i = 10
def read() = {
i = math.max(0, i) - 1
i
}
override def close() = println("closed") // looking for this
}
Enumerator.fromStream(inputStream)(Iteratee.foreach(a => 1 / 0)).onComplete(println)
我们只看到:
Failure(java.lang.ArithmeticException: / by zero)
流从未关闭。将1 / 0 替换为1 / 1,您会看到流关闭了。
当然,我可以保持对原始流的引用并在失败时关闭它,但 AFAIK 使用 iteratees 的想法是创建可组合的迭代而不必这样做。
这是预期的行为吗?
有没有办法使用迭代器以便始终正确处理资源?
【问题讨论】:
-
请注意,这种行为在 2.2 中发生了变化(尽管它仍然有点奇怪)。我从来没有真正认为 Play 的迭代实现有一个非常好的资源管理故事。
标签: scala playframework-2.1 iterate resource-management