InputStream
作为参数从某处传递,在那里它将被进一步处理然后关闭。所以我不想在这里关闭InputStream
。请考虑以下代码:
void readInputStream(final InputStream inputStream) {
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine() != null) {
// do my thing
}
}
根据另一篇Stackoverflow文章,如果我关闭BufferedReader
和/或InputStreamReader
,那么底层的InputStream
也将被关闭。
我的问题:读者是否需要关闭,即使底层的InputStream
在其他地方关闭了?不关闭读者会导致内存泄漏吗?
读者是否需要关闭,即使基础
InputStream
在其他地方关闭?
不,他们绝对不需要在那种情况下。但无论如何关闭它们通常是一个好主意。
不关闭读者会导致内存泄漏吗?
不,没有内存泄漏,假设Reader
本身一旦完成就无法访问。此外,Reader
通常不会使用大量内存。
更重要的问题是你是否可以通过不关闭Reader
来获得资源泄漏。答案是......这取决于。
InputStream
将永远在应用程序的其他地方关闭,那么它会处理可能的内存泄漏。但是如果你关闭了Reader
那么底层的InputStream
将被关闭。
在close()
上不止一次调用InputStream
是无害的,几乎没有任何成本。
你不应该关闭Reader
的唯一情况是关闭底层InputStream
是错误的。例如,如果关闭SocketInputStream
,则应用程序的其余部分可能无法重新建立网络连接。同样,与InputStream
相关的System.in
通常不能重新打开。
在这种情况下,允许您在方法中创建的Reader
被垃圾收集实际上是安全的。与InputStream
不同,典型的Reader
类不会覆盖Object::finalize()
来关闭其数据来源。
@Pshemo提出了一个关于系统设计的重要观点。
如果你接受一个InputStream
作为参数,那么用当地的Reader
包裹它可能是错误的...尤其是BufferedReader
。 `BufferedReader容易在流上预读。如果在方法返回后调用者将使用该流,则任何已读入缓冲区但未被此方法使用的数据都可能丢失。
更好的想法是呼叫者通过Reader
。或者,此方法应记录为取得InputStream
的所有权。在那种情况下,它应该始终close()
它。