Java 在重用FileOutputStream时是否应该关闭流?

Java 在重用FileOutputStream时是否应该关闭流?,java,fileoutputstream,Java,Fileoutputstream,如标题中所述,在重用FileOutputStream变量时是否应关闭流?例如,在以下代码中,我应该在为其分配新文件之前调用outfile.close(),为什么 谢谢:) 是。处理完一个文件(流)后,应始终将其关闭。因此,与文件(流)一起分配的资源将被释放到操作系统,如文件描述符、缓冲区等 Java文档 关闭此文件输出流并释放与此流关联的所有系统资源。此文件输出流可能不再用于写入字节 未关闭的文件描述符甚至可能导致java程序中的资源泄漏 我认为这里的混淆是围绕着“重用”文件输出流的概念。您所做

如标题中所述,在重用FileOutputStream变量时是否应关闭流?例如,在以下代码中,我应该在为其分配新文件之前调用
outfile.close()
,为什么

谢谢:)


是。处理完一个文件(流)后,应始终将其关闭。因此,与文件(流)一起分配的资源将被释放到操作系统,如文件描述符、缓冲区等

Java文档

关闭此文件输出流并释放与此流关联的所有系统资源。此文件输出流可能不再用于写入字节


未关闭的文件描述符甚至可能导致java程序中的资源泄漏

我认为这里的混淆是围绕着“重用”文件输出流的概念。您所做的只是通过将一个新值与之关联,重新使用一个标识符(变量的名称
outfile
)。但这对Java编译器来说只有语法意义。名称所指的对象--
FileOutputStream
–只是简单地放在地板上,最终会在未指定的时间点被垃圾收集。对曾经引用它的变量做什么并不重要。无论您是将其重新分配给另一个
FileOutputStream
,还是将其设置为
null
,还是让其超出范围,都是一样的


调用
close
显式地将所有缓冲数据刷新到文件中,并释放相关资源。(垃圾回收器也会释放它们,但您不知道什么时候会发生这种情况。)请注意,
close
也可能抛出一个
IOException
,因此真正重要的是您知道尝试操作的时间点,只有在显式调用该函数时才这样做。

即使没有自动资源管理,或者(请参见下文),您的代码可以变得更加可读和可靠:

for (int index = 1; shouldCreateNewFile(); ++index) {
  FileOutputStream outfile = new FileOutputStream(index + ".txt");
  try {
    outfile.write(getNewFileContent());
  }
  finally {
    outfile.close();
  }
}
但是,Java 7为闭包引入了一种新的语法,这种语法在出现错误时更可靠,信息更丰富

for (int index = 1; shouldCreateNewFile(); ++index) {
  try (FileOutputStream outfile = new FileOutputStream(index + ".txt")) {
    outfile.write(getNewFileContent());
  }
}
输出流仍将关闭,但如果
try
块中存在异常,并且在关闭流时出现另一异常,则该异常将被抑制(链接到主异常),而不是像前面的示例那样导致主异常被丢弃

您应该始终在Java 7或更高版本中使用自动资源管理。

“在我为其分配新文件之前”-是的,您可以将更改保留在缓冲区中,这意味着这些更改可能不会保存到文件中。您正在使用文件句柄,而这些句柄在操作系统中是有限的资源。您正在占用JVM中的资源。您应该始终自己整理。请查看处理可关闭资源的更好解决方案
for (int index = 1; shouldCreateNewFile(); ++index) {
  try (FileOutputStream outfile = new FileOutputStream(index + ".txt")) {
    outfile.write(getNewFileContent());
  }
}