我对使用Java InputStreams时close()方法的用法有一些疑问.从我看到和从大多数开发人员那里读到的内容,你应该总是在不再需要的时候在InputStream上显式调用close().但是,今天我正在研究使用Java属性文件,我发现的每个例子都有这样的:
Properties props = new Properties();
try {
props.load(new FileInputStream("message.properties"));
//omitted.
} catch (Exception ex) {}
Run Code Online (Sandbox Code Playgroud)
使用上面的示例,无法显式调用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.
}
}
Run Code Online (Sandbox Code Playgroud)
哪种方式更好和/或更有效?或者它真的重要吗?
Jon*_*Jon 48
Properties类将输入流包装在LineReader中以读取属性文件.由于您提供输入流,因此您有责任关闭它.
第二个例子是到目前为止处理流的更好方法,不要依赖别人为你关闭它.
你可以做的一个改进是使用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);
}
Run Code Online (Sandbox Code Playgroud)
Dan*_*ina 33
我会尝试使用资源(至少对于Java 7+):
Properties props = new Properties();
try(InputStream fis = new FileInputStream("message.properties")) {
props.load(fis);
//omitted.
} catch (Exception ex) {
//omitted.
}
Run Code Online (Sandbox Code Playgroud)
退出try块时,应自动调用close()调用.
Bil*_*ard 26
属性教程中的示例在FileInputStream加载后显式关闭,因此我认为可以安全地假设该load方法不对它负责,你是.
// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();
Run Code Online (Sandbox Code Playgroud)
仅供参考,我检查了Apache的和谐的执行性能,它并没有在负载关闭流.
小智 14
如果您使用的是Java 7+,则可以使用:
try(InputStream is = new FileInputStream("message.properties")) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
Adr*_*ith 13
在文档中没有提到props.load将关闭输入流.您应该像您建议的那样在finally块中手动关闭输入流.
函数关闭是不正常的InputStream.同样的约定适用于非垃圾收集语言中的内存:如果可能,打开流的人应该关闭流.否则,很容易让一个流打开(你认为一个函数会关闭它,但它没有,或者什么......)
看起来第一个代码示例最终依赖于FileInputStream中的finalize方法来实际关闭文件.我会说你的第二个例子更好,即使在这两种情况下文件都会关闭.
有些像Byte流这样的情况,close什么都不做,可以省略,否则我认为最好在finally块中显式关闭文件.如果你打开它,你关闭它.
Oracle网站上有一本名为Java Platform Performance的书,它在附录中讨论了终结器,它说:
你几乎总是更好地做自己的清理,而不是依靠终结器.使用终结器还可以留下在不确定的时间内无法恢复的关键资源.如果您正在考虑使用终结器来确保及时释放重要资源,您可能需要重新考虑.
让我在其他人的答案中添加一些内容。
如果您可以导入Apache Commons IO,您可以使用非常方便的AutoCloseInputStreams 类:您包装您的InputStream实例,然后您只需使用您的包装实例,一旦到达输入末尾或当流被显式关闭,以先到者为准。
| 归档时间: |
|
| 查看次数: |
81045 次 |
| 最近记录: |