Java 即使InputStream保持打开状态,我是否需要关闭InputStreamReader?
Java 即使InputStream保持打开状态,我是否需要关闭InputStreamReader?,java,memory,memory-management,bufferedreader,inputstreamreader,Java,Memory,Memory Management,Bufferedreader,Inputstreamreader,InputStream作为参数从某个地方传递,在那里它将被进一步处理,然后关闭。所以我不想在这里关闭InputStream。考虑下面的代码: void readInputStream(final InputStream inputStream) { final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); String line; while
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
在其他地方关闭,读卡器也需要关闭吗
不,他们绝对不需要在那种情况下。但无论如何,关闭它们通常是个好主意
不关闭读卡器会导致内存泄漏吗
不,没有内存泄漏,假设读卡器本身在您使用完后变得不可访问。此外,阅读器
通常不会占用大量内存
更重要的问题是,如果不关闭读卡器
,是否会导致资源泄漏。答案是。。。视情况而定
- 如果您可以保证底层的
InputStream
始终在应用程序中的其他位置关闭,那么就可以解决可能的内存泄漏问题
- 如果您不能保证这一点,那么就有资源泄漏的风险。底层操作系统级文件描述符在(例如)Linux中是有限的资源。如果JVM不关闭它们,它们可能会耗尽,并且某些系统调用将开始意外失败
但如果确实关闭了读取器
,则底层的输入流
将被关闭
在InputStream
上多次调用close()
是无害的,而且几乎不需要任何成本
您不应该关闭读卡器的唯一情况是关闭底层InputStream
是错误的。例如,如果关闭一个SocketInputStream
,应用程序的其余部分可能无法重新建立网络连接。同样,与系统中的相关的输入流
通常无法重新打开
在这种情况下,允许对方法中创建的读取器进行垃圾收集实际上是安全的。与InputStream
不同,典型的Reader
类不会重写Object::finalize()
以关闭其数据源
@Pshemo提出了系统设计的一个要点
如果您接受一个InputStream
作为参数,那么使用本地读取器将其包装可能是错误的。。。尤其是缓冲读取器
。BufferedReader
易于在流上进行预读。如果在方法返回后调用方将使用该流,则任何已读入缓冲区但未被该方法使用的数据都可能丢失
更好的办法是让调用方传递一个读取器
。或者,应该将此方法记录为拥有InputStream
。在这种情况下,它应该总是关闭()
它。是的,需要关闭读卡器。使用代理,例如,防止关闭传递的参数
void readInputStream(InputStream inputStream) throws IOException{
try (var bufferedReader = new BufferedReader(new InputStreamReader(
new CloseShieldInputStream(inputStream)))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
// do my thing
}
}
}
JIC:与输入屏蔽类似,Apache Commons I/O还提供了一个输出屏蔽,以解决关闭包装输出流的类似问题,-
有关更详细的考虑,请参考原始答案。@stephen-c的积分我不完全理解您的问题,但一般来说,是的,这样的资源应该在您使用完之后关闭。另外,我建议您看看try with resources,它会自动为您关闭它们。最后,对于这个问题,您的代码片段不是最合适的。您的方法可能不应该创建自己的BufferedReader
,而是将其作为参数接受。这样,您的应用程序中将有一个BufferedReader,当不再需要它时可以关闭它,这也将关闭底层的InputStream
@Pshemo。InputStream被传递给不同的处理程序,这些处理程序使用它做不同的事情。每次之前重置(最后关闭)。只有这个处理程序实际上需要一个BufferedReader,另一个处理程序只是将InputStream传递给库函数等等。我的用例是用户可以上传一个文件,并且这个文件可以由许多不同的处理程序解释。因此,第一个处理程序尝试读取特定格式的文件,如果不是该格式,下一个处理程序将读取该文件,依此类推。每次新处理程序读取inputstream时,都会重置该inputstream。这就是它被传播的原因。但你的回答证实了我的想法,谢谢:)