我对使用Java InputStreams时close()方法的使用有一些疑问。从大多数开发人员的经验来看,当不再需要InputStream时,应该始终在InputStream上显式调用close()。但是,今天我正在研究使用Java属性文件,并且发现的每个示例都具有以下内容:
Properties props = new Properties();
try {
props.load(new FileInputStream("message.properties"));
//omitted.
} catch (Exception ex) {}
在上面的示例中,没有办法显式调用close(),因为在使用InputStream后无法访问它。我看过InputStreams的许多类似用法,尽管它似乎与大多数人所说的显式关闭相矛盾。我通读了Oracle的JavaDocs,但没有提到Properties.load()方法是否关闭InputStream。我想知道这通常是否可以接受,或者是否更喜欢执行以下操作:
Properties props = new Properties();
InputStream fis = new FileInputStream("message.properties");
try {
props.load(fis);
//omitted.
} catch (Exception ex) {
//omitted.
} finally {
try {
fis.close();
} catch (IOException ioex) {
//omitted.
}
}
哪种方法更好和/或更有效?还是真的重要吗?
Properties Tutorial中的示例在加载后显式关闭FileInputStream
,所以我认为可以肯定地认为load
方法对此不负责。
// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();
仅供参考,我检查了Apache Harmony的Properties实现,它确实[[not关闭加载的流。
第二个示例是到目前为止处理流的更好的方法,不要依赖其他人为您关闭它。
您可以做的一项改进是使用IOUtils.closeQuietly()
以关闭流,例如:
Properties props = new Properties();
InputStream fis = new FileInputStream("message.properties");
try {
props.load(fis);
//omitted.
} catch (Exception ex) {
//omitted.
} finally {
IOUtils.closeQuietly(fis);
}
Properties props = new Properties();
try(InputStream fis = new FileInputStream("message.properties")) {
props.load(fis);
//omitted.
} catch (Exception ex) {
//omitted.
}
退出try块时应自动调用close()调用。
try(InputStream is = new FileInputStream("message.properties")) {
// ...
}
props.load
将关闭输入流。您应该像建议的那样在finally块中手动关闭输入流。[函数关闭InputStream
是不正常的。使用与非垃圾收集语言中的内存相同的约定:如果可能,打开流的人应该关闭流。否则,很容易让流保持打开状态(您以为函数会关闭它,但是它没有,或者什么...)
[在某些情况下,像Byte流这样,close什么都不做,可以省略,否则,我认为最好在finally块中明确关闭文件。如果打开它,则将其关闭。
[Oracle网站上有一本书Java Platform Performance,在其附录中讨论了终结器,它说:
几乎总是最好自己进行清理,而不要依赖终结器。使用终结器也可能会留下关键资源,这些资源在不确定的时间内无法恢复。如果您正在考虑使用终结器来确保及时释放重要资源,则可能需要重新考虑。
如果可以导入Apache Commons IO,则可以使用非常方便的AutoCloseInputStream
s类:包装AutoCloseInputStream
,然后只使用包装的实例,当实例已达到输入的末尾或显式关闭流时,以先到者为准。