你需要关闭溪流吗?

Syn*_*les 5 java syntax inputstream

这个问题分为两部分:

InputStream i1 = new InputStream()和之间有什么区别new InputStream()
并且
是否值得它来创建所有局部变量只是关闭它们?

我知道简单的答案,第一个你可以保留变量,继续使用变量,甚至关闭输入流像一个优秀的程序员.第二个你失去了它的参考,但它看起来更简洁.这两者之间有什么记忆差异吗?速度差(毁灭性)怎么样?

现在来看一些刺激我思想的例子.首先我们使用`'new Object()`而无需抛弃它.

 public void getLongStrings() throws IOException {
        try {
            foo = FileCopyUtils.copyToString(new InputStreamReader(aBook.getInputStream()));
            bar = FileCopyUtils.copyToString(new InputStreamReader(aNovel.getInputStream()));
        }
        catch (IOException ioe) {
            //do something appropriate here;
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在为更详细的方法

public void getLongStrings() throws IOException {
        InputStream i1 = null;
        InputStream i2 = null;
        InputStreamReader isr1 = null;
        InputStreamReader isr2 = null;
        try {
            i1 = aBook.getInputStream();
            i2 = aNovel.getInputStream();
            isr1 = new InputStreamReader(i1);
            isr2 = new InputStreamReader(i2);
            foo = FileCopyUtils.copyToString(isr1);
            bar = FileCopyUtils.copyToString(isr2);
        }
        catch (IOException ioe) {
            //do something appropriate here
        } finally {
            if (i1 != null) i1.close();
            if (i2 != null) i2.close();
            if (isr1 != null) isr1.close();
            if (isr2 != null) isr2.close();
        }
    }
Run Code Online (Sandbox Code Playgroud)

第一个还是第二个更好?一个比另一个快吗?关闭所有我的流是否很聪明,即使它看起来不漂亮?

感谢您的任何见解(或编辑).

Jon*_*eet 7

第二个你失去了它的参考,但它看起来更简洁.

是的,它更简洁.你对这个对象做的很少 - 重要的是,你没有做你应该做的事情.采用快捷方式通常会产生较少的代码,但是在终结器关闭的情况下保持打开文件句柄,您会发现您将获得难以可靠再现的异常.

这两者之间有什么记忆差异吗?

也许,但这不相关.这里重要的资源不是内存,而是文件句柄.

速度差(毁灭性)怎么样?

再次,可能是无关紧要的.正确性更为重要.

(请注意,您当前的第二个代码仍然不完全可靠 - 如果其中一个早期close()调用抛出异常,则不会关闭其余代码.)

如果您使用的是Java 7,则应该查看try-with-resources语句,这样可以使所有这些变得更加简单.

编辑:正如JB Nizet的回答所述,你正在使用的代码可能已经关闭了底层流 - 它取决于它是什么FileCopyUtils.如果是Spring课程,你没事.如果它是其他东西,你可能不是.你应该阅读文档.一般原则如上所述:你应该确保某些东西关闭了流.不要以为只是因为在这种情况下你不需要明确地关闭事物,这在一般情况下是正确的.

需要注意的是番石榴InputSupplierOutputSupplier接口都在这里有用-它允许你绕过供应商明知输入/输出没有被打开 ...这意味着其他代码可以执行打开/复制/关闭(或任何是必需的)并为您处理所有...您最终不会使用代码中可能被关闭的任何对象.