输入/输出流在销毁时是否关闭?

2022-09-05 00:39:01

Java 中的 InputStreams 和 OutputStreams 是否在销毁时关闭()?我完全理解这可能是不好的形式(特别是在C和C++世界中),但我很好奇。

另外,假设我有以下代码:

private void foo()
{
    final string file = "bar.txt";
    Properties p = new Properties();
    p.load( new FileInputStream(file) );
    //...
}

无名的FileInputStream是否在p.load()之后超出范围,因此被销毁,有点像C++范围规则?我尝试在Google上搜索java的匿名变量范围,但这并没有发现我想象的那样。

谢谢。


答案 1

第一个答案:Java中没有“破坏”(C++意义上的)这样的东西。只有垃圾回收器,当它看到一个准备被收集的对象时,它可能会也可能不会唤醒并完成它的工作。Java 中的 GC 通常是不可信的。

第二个答案:有时是,有时不是,但不值得冒险。来自Elliote Rusty Harold的Java IO

并非所有流都需要关闭—例如,字节数组输出流不需要关闭。但是,与文件和网络连接关联的流在完成操作后应始终关闭。例如,如果您打开一个文件进行写入,而忽略了在完成时将其关闭,则可能会阻止其他进程读取或写入该文件。

根据Harold的说法,输入或输出流也是如此。有一些例外(他 System.in 指出),但总的来说,如果你在完成后不关闭文件流,你就会冒险。并在最后的块中关闭它们,以确保即使抛出异常,它们也会被关闭。


答案 2

我曾经假设流最终会通过垃圾回收自动关闭,但轶事证据表明,手动关闭它们会导致资源泄漏。您将需要执行如下操作:

InputStream stream = null;

try {
  stream = new FileInputStream("bar.txt");
  Properties p = new Properties();
  p.load(stream);
}
catch(Exception e) {
  // error handling
}
finally {
  closeQuietly(stream);
}

closeQuietly()是 Apache 的 commons-io 库中的一种方法。IOUtils