0

我正在查看由这个答案提示的scala-arm库,它看起来非常适合在大多数情况下管理资源。

但是,有一个上下文,乍一看似乎无法处理:将资源“移交”给另一个资源。这在使用 I/O 时经常出现:

for (fin <- managed(new FileInputStream(file));
     // almost what we want, except see below
     gzip <- managed(new GZIPInputStream(fin));
     src <- managed(Source.fromInputStream(gzip))) {
  /* some fancy code */
}

现在,问题是这样的:如果gzip成功创建,那么负责关闭fin,并且fin不应该关闭(更新:这不太正确 - 双重关闭很好;请参阅接受的答案)。不过,另一种选择:

for (src <- managed(Source.fromInputStream(
              new GZIPInputStream(new FileInputStream(file))))) {
  /* some fancy code */
}

不太正确 - 如果GZIPInputStream构造函数中存在(不可否认的)错误,FileInputStream则不会关闭。同上fromInputStream

scala-arm(或其他一些包)是否提供了一种我还没有找到的安全处理这种清理的工具?

4

2 回答 2

3

又看了几分钟,发现真的没关系。java.io.Closeable规定close()ing 已经关闭的资源是无操作的。所以把所有东西都包起来managed并让它双重关闭是安全的。因此,第一个代码示例是正确的。

于 2012-01-05T17:34:55.333 回答
1

对我来说最好的方法是使用 iteratee、enumerator 和 enumeratee 的概念,它在函数世界中有其基础。

您可能感兴趣的是具有非常好的实现的 Scalaz 库。

换句话说,使用这些概念是为了让源上的迭代器知道consummator何时结束consuming,但反过来也一样。知道来源的缺点无济于事。

编辑

这是一篇关于 iteratee 用途的非常明确的帖子。查看讨论您的问题的动机参数......无论何时发生好或坏,但在正确的时间关闭资源

于 2012-01-05T21:33:40.833 回答