让我们说我使用的是一个记录不完整的第三方库,其中没有源代码可用。其中一个库的方法接受InputStream
来加载各种数据。
由于缺少文档,一旦用完它就不清楚该方法是否关闭了流,所以一种可能的解决方案可能就是试一试这个方法。 - 资源,只是为了安全起见。
不幸的是,Java规范(据我所知)没有提到如果在try-with-resource中手动关闭资源会发生什么。有人碰巧知道吗?
答案 0 :(得分:10)
它完全取决于资源本身的实现。 try-with-resource语句在close()
块中调用finally
(并保留异常等)是“只是”语法糖(但非常甜蜜)。
只要流支持close()
被调用两次 - 我希望大多数实现都这样做,并且InputStream
的契约需要 - 它绝对没问题。
请注意,您熟悉将一种资源包装在另一种资源中,例如,
。try (InputStream input = new FileInputStream(...)) {
try (Reader reader = new InputStreamReader(input, ...)) {
...
}
}
或者使用一个try-with-resources语句:
try (InputStream input = new FileInputStream(...);
Reader reader = new InputStreamReader(input, ...)) {
...
}
在这两种情况下,都会有两个finally
块,因此首先调用reader.close()
,然后调用input.close()
- 但reader.close()
无论如何都会关闭input
。
答案 1 :(得分:6)
Closeable
(因此,close()
)的方法InputStream
必须是幂等的:
如果流已经关闭,则调用此方法无效。
因此,不止一次关闭InputStream
是安全的。
但是,更通用的AutoCloseable
接口不要求其close()
方法具有幂等性,因此对Closeable
以外的资源执行相同操作可能不安全:
请注意,与Closeable的close方法不同,此close方法不需要是幂等的。换句话说,不止一次调用此close方法可能会产生一些可见的副作用,这与Closeable.close不同,如果多次调用则需要它无效。但是,强烈建议强制使用此接口的实现者使其接近的方法具有幂等性。
答案 2 :(得分:2)
规范确实说明了一切:如果resource.close()
抛出异常,那么异常将从构造中抛出。
当然,规范无法知道任何特定的close
方法是否会抛出异常。要找到它,你必须测试你的特定资源。
答案 3 :(得分:0)
您可以尝试在finally语句中关闭它。
InputStream stream = null;
try {
stream = new InputStream();
yourMethod(stream);
} catch (...) {
} finally {
try {
stream.close()
} catch (IOException ioe) {
// can throw IOException while closing closed stream
}
}