closuresJava InputStreams

在使用Java InputStream时,我对使用close()方法有一些疑问。 从我看到并从大多数开发人员那里阅读的内容,您应该总是在不再需要的时候,在InputStream上显式调用close()。 但是,今天我正在研究使用Java属性文件,我发现每个例子都是这样的:

Properties props = new Properties(); try { props.load(new FileInputStream("message.properties")); //omitted. } catch (Exception ex) {} 

通过上面的例子,没有办法显式地调用close(),因为InputStream在使用后是不可访问的。 我已经看到了InputStream的许多类似的用法,尽pipe它似乎与大多数人关于明确closures的内容相矛盾。 我通过Oracle的JavaDocs阅读,并没有提到如果Properties.load()方法closuresInputStream。 我想知道这是普遍接受还是更喜欢做更像下面的事情:

 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. } } 

哪种方法更好和/或更高效? 还是真的很重要?

在“ 属性教程 ”中的示例在加载后明确地closures了FileInputStream ,所以我认为可以安全地假设load方法不负责任。

 // create and load default properties Properties defaultProps = new Properties(); FileInputStream in = new FileInputStream("defaultProperties"); defaultProps.load(in); in.close(); 

仅供参考,我检查了属性的Apache Harmony实现,并且不会在加载时closuresstream。

Properties类将inputstream包装在LineReader中以读取属性文件。 由于您提供了inputstream,因此您有责任closures它。

第二个例子是一个更好的方法来处理这个stream,不要依赖别人来为你closures它。

你可以做的一个改进就是使用IOUtils.closeQuietly()

http://commons.apache.org/io/api-1.2/org/apache/commons/io/IOUtils.html#closeQuietly(java.io.InputStream);

closuresstream,例如:

 Properties props = new Properties(); InputStream fis = new FileInputStream("message.properties"); try { props.load(fis); //omitted. } catch (Exception ex) { //omitted. } finally { IOUtils.closeQuietly(fis); } 

我会尝试与资源(至less对于Java 7+):

 Properties props = new Properties(); try(InputStream fis = new FileInputStream("message.properties")) { props.load(fis); //omitted. } catch (Exception ex) { //omitted. } 

当try块退出时,应该自动调用close()调用。

在文档中没有提到props.load会closuresinputstream。 你应该像你所build议的那样,在finally块中手动closuresinputstream。

一个函数closures一个InputStream是不正常的。 相同的约定适用于非垃圾收集语言的内存:如果可能,打开stream的人应closuresstream。 否则,打开一个stream是很容易的(你认为一个函数会closures它,但是它不会,或者是某个东西)

它看起来像第一个代码示例最终依靠FileInputStream中的finalize方法来实际closures文件。 我会说你的第二个例子是更好的,即使在这两种情况下文件确实closures。

有一些像Bytestream那样的情况,close什么都不做,可以省略,否则我认为最好在finally块中closures文件。 如果你打开它,就closures它。

甲骨文网站上有一本名为“ Java平台性能”的书,它在附录中讨论了终结器,它说:

你几乎总是做自己的清理,而不是依靠终结者。 使用终结器也可能会留下不能在无限的时间内恢复的关键资源。 如果您正在考虑使用终结器来确保及时释放重要资源,则可能需要重新考虑。

如果你使用的是Java 7+,你可以使用这个:

 try(InputStream is = new FileInputStream("message.properties")) { // ... } 

让我给别人的答案增加一点点。

如果你可以导入Apache Commons IO ,那么你可以使用如此方便的AutoCloseInputStream类:包装你的InputStream ,然后你只需使用你的包装实例,一旦达到input结束就自动closures或当stream明确closures时,以先到者为准。