尝试使用资源使用InputStreamReader将流包装在哪里?
我可能想多了,但我只是写了代码:
try (InputStream in = ModelCodeGenerator.class.getClassLoader().getResourceAsStream("/model.java.txt"))
{
modelTemplate = new SimpleTemplate(CharStreams.toString(new InputStreamReader(in, "ascii")));
}
这意味着InputStreamReader永远不会关闭(但在本例中,我们知道它的Close方法只关闭基础InputStream。)
可以这样写:
try (InputStreamReader reader = new InputStreamReader(...))
但这似乎更糟糕。如果InputStreamReader出于某种原因抛出,InputStream将永远不会关闭,对吗?这是C++中调用其他构造函数的构造函数的常见问题。异常可能导致内存/资源泄漏。
这里有没有最佳实践?
解决方案
这意味着InputStreamReader永远不会关闭
嗯?在您的代码中,它是...它当然也会处理您的资源流的.lose()。有关更多详细信息,请参阅下面的内容...
As @SotiriosDelimanolis mentions但是,您可以在try-with-resource语句的"resource块"中声明多个资源。
您现在有另一个问题:.getResourceAsStream()
可以返回NULL;因此您可能有NPE。
如果我是你,我会这么做:
final URL url = ModelCodeGenerator.class.getClassLoader()
.getResource("/model.java.txt");
if (url == null)
throw new IOException("resource not found");
try (
final InputStream in = url.openStream();
final Reader reader = new InputStreamReader(in, someCharsetOrDecoder);
) {
// manipulate resources
}
有一个非常重要的问题需要考虑但是...
Closeable
确实扩展了AutoCloseable
;事实上,它的不同之处只是抛出的异常(IOException
vsException
)。但行为有根本区别。
来自AutoCloseable
的.close()
的javadoc(重点是我的):
请注意,与Closeable的Close方法不同,此Close方法不要求是幂等的。换句话说,多次调用此Close方法可能会产生一些明显的副作用,这与Closeable.Close不同,Closeable.Close在多次调用时必须无效。但是,强烈建议此接口的实现者使他们的Close方法是幂等的。
确实,Closeable
的javadoc对此很清楚:
关闭此流并释放与其关联的所有系统资源。如果流已经关闭,则调用此方法不会产生任何效果。
您有两点非常重要:
- 根据合同,
Closeable
还负责与其关联的所有资源;因此,如果关闭包装了InputStream
的Reader
的BufferedReader
,则所有这三个资源都将关闭; - 如果您多次调用
.close()
,则不会有进一步的副作用。
当然,这也意味着您可以选择Paranid选项并保留对所有Closeable
资源的引用,然后关闭它们;但是,如果您的混合中有AutoCloseable
资源而不是Closeable
!
相关文章