【发布时间】:2018-08-29 07:39:42
【问题描述】:
在Thinking in Java一书中,有人说
请注意,任何打开文件的代码都会在 finally 子句中保护文件的 close() 调用,以保证文件将被正确关闭。
但是其他来源或汇呢?至少目前我知道stdin、stdout、stderr 和ByteArrayInputStream、ByteArrayOutputStream 不需要关闭d。
至于stdin、stdout、stderr我有两个理由不用关闭:
- 它们是 singleton 在 Java run-time
-
stdin的sink是屏幕,stdout和stderr的source是键盘,失去与屏幕和键盘的连接是没有意义的
关于ByteArrayInputStream 和ByteArrayOutputStream,Java 文档告诉:
关闭 ByteArrayInputStream 无效。该类中的方法可以在流关闭后调用,不会产生 IOException。
我猜这可能是由于 array 位于磁盘以外的易失性内存中
但是我对这些分析非常肯定,所以我想得到更准确和授权的答案,特别是,当我们自己设计流时,什么时候必须关闭流,什么时候不需要?
同时,我想确认我关于不必要关闭的推理是可以的,或者,如果有人可以提供更多理由,将不胜感激
【问题讨论】:
-
您也可以使用 Java 的 try-with-resources docs.oracle.com/javase/tutorial/essential/exceptions/… 而不是编写大量 finally 块来关闭流等
-
是的,但仍然很高兴知道为什么不需要关闭像
stdin、stdout、stderr这样的某些流 -
一般来说,只要需要使用,所有流都需要保持打开状态。这包括您自己打开的流,以及系统流
stdin、stdout和stderr。系统流也不例外。同样的规则也适用于他们。系统流在开始时由 Java 内部打开,在应用程序结束时由 Java 内部关闭。为什么要提前关闭它们? -
顺便提一下,当心
close()方法关闭被包装对象的“包装”对象。例如,如果您创建了一个用System.in初始化的Scanner,则不要关闭它;否则,你会无意中关闭System.in。 -
@Rui 绝对 - 这就是为什么我将其添加为评论而不是答案,但很高兴知道 Java 有助于将多行模式减少到更合理的程度。