Предположим, я читал из 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
, и вы увидите, что поток закрывается.
Конечно, я мог бы сохранить ссылку на исходный поток и закрыть его в случае сбоя, но, насколько мне известно, идея использования итераций заключается в создании компонуемой итерации без необходимости этого делать.
Это ожидаемое поведение?
Есть ли способ использовать итерации, чтобы ресурсы всегда располагались правильно?