gpt4 book ai didi

scala - Iteratee 管理资源安全吗?

转载 作者:行者123 更新时间:2023-12-01 22:06:29 25 4
gpt4 key购买 nike

假设我正在从 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,您将看到流关闭。

当然,我可以维护对原始流的引用并在失败时关闭它,但据我所知,使用迭代器的想法是创建可组合迭代,而不必这样做。

<小时/>
  1. 这是预期的行为吗?

  2. 有没有办法使用 iteratees 以便始终正确地处理资源?

最佳答案

Iteratees 是专门为安全资源管理而设计的。请参阅 Iteratee IO: safe, practical, declarative input processing 的第一句:

Iteratee IO is a style of incremental input processing with precise resource control.

这个想法是,当您的资源仅通过迭代器访问时,拥有资源的代码可以准确地告诉迭代器何时完成资源的使用并立即关闭它。另一方面,当手动管理迭代时(与传统的InputStream 一样),资源的用户负责关闭它。这可能会导致泄漏。

话虽如此,Play 2.1 中存在一个错误,其中 fromStream 无法管理其底层 InputStream 的关闭!此错误已在 Play 2.2 中修复。

您可以看到fromStream code查看如何通过使用 onDoneEnumerate 在 iteratee 完成时关闭资源来修复 Enumerator

关于scala - Iteratee 管理资源安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24976145/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com