2012-01-05 109 views
0

我看scala-arm库,通过this answer提示,它看上去很不错,在大多数环境中管理资源。管理Scala中关闭资源的最佳方式是什么?

虽然有一个上下文,乍一看,它似乎无法处理:将资源“切换”到另一个资源。这与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,然后负责关闭不应该关闭(更新:这是不完全正确 - 双密切的罚款;见接受的答案)。另一种选择,虽然:

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

是不太正确的 - 如果在GZIPInputStream构造函数(当然不可能)错误,FileInputStream未关闭。同上fromInputStream

scala-arm(或其他软件包)是否提供安全处理这个清理工具的工具,我还没找到?

回答

3

做了找了几分钟,发现它其实并不重要。 java.io.Closeable规定,close()荷兰国际集团已关闭的资源是一个空操作。因此,将所有内容都包装在managed中并让其双关闭是安全的。因此,第一个代码示例是正确的。

1

对我来说,最好的方法是使用迭代器,枚举器和枚举器的概念,它在功能世界中具有基础。

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

有人说这些概念是为了让源头上的迭代器知道消费者何时结束消费而且还有其他方式。知道源的缺点没有什么可提供的。

编辑

这里是什么iteratee是一个非常明确的post。看到关于你的问题的动机参数......关闭资源,无论什么时候做得好或错误,但在正确的时间

+0

我不太清楚你的意思,特别是“让知道源头没有任何东西提供”。我的问题不是在完成时关闭;即使我无法成功设置输入链,也要确保文件已关闭。 – 2012-01-08 00:15:29

+0

其实这个迭代器,枚举器和枚举在那里,以解决(和其他)的情况。当源完成生产(你不关心的东西)和消费者完成时(如果实际上失败了,它已经完成)。我要补充一个非常有用的帖子,将微启你关于这个问题(这是** **你关注的解决方案) – 2012-01-08 00:25:42

+0

谢谢 - 该职位确实有很大的帮助。它看起来像一个有趣的解决方案,尽管假设一切都是围绕着Iteratees构建的。看起来不像它直接适用于使用Java的标准过滤流和阅读器,但他们对Iteratees一无所知。 – 2012-01-08 01:03:08

相关问题