重用 FileOutputStream 时应该关闭流吗?
Should I close stream when reusing FileOutputStream?
如标题所述,在重用 FileOutputStream 变量时是否应该关闭流?例如,在下面的代码中,我应该在分配新文件之前调用 outfile.close()
吗?为什么?
谢谢:)
FileOutputStream outfile = null;
int index = 1;
while (true) {
// check whether we should create a new file
boolean createNewFile = shouldCreateNewFile();
//write to a new file if pattern is identified
if (createNewFile) {
/* Should I close the outfile each time I create a new file?
if (outfile != null) {
outfile.close();
}
*/
outfile = new FileOutputStream(String.valueOf(index++) + ".txt");
}
if (outfile != null) {
outfile.write(getNewFileContent());
}
if (shouldEnd()) {
break;
}
}
try {
if (outfile != null) {
outfile.close();
}
} catch (IOException e) {
System.err.println("Something wrong happens...");
}
YES. 一旦你完成了一个文件(流),你应该总是关闭它。这样分配给文件(流)的资源将被释放给操作系统,如文件描述符、缓冲区等。
Java 文档 FileOutputStream.close()
Closes this file output stream and releases any system resources associated with this stream. This file output stream may no longer be used for writing bytes.
未关闭的文件描述符甚至会导致 java 程序中的资源泄漏。 Reference
我认为这里的混淆围绕着“重用”FileOutputStream
的概念。您所做的只是通过将新值与其关联来重新使用 identifier(变量的名称 outfile
)。但这仅对 Java 编译器具有语法意义。名称所指的 object – FileOutputStream
– 被简单地丢弃在地板上,最终将在未指定的稍后时间点被垃圾收集。对曾经引用它的变量做什么并不重要。无论您重新分配它另一个 FileOutputStream
、将其设置为 null
还是让它超出范围都是一样的。
调用close
显式将所有缓冲数据刷新到文件并释放相关资源。 (垃圾收集器也会释放它们,但你不知道这会在什么时候发生。)请注意 close
也可能会抛出 IOException
所以你知道操作的时间点真的很重要尝试过,只有在显式调用该函数时才会这样做。
即使没有自动资源管理,或 try-with-resources(见下文),您的代码也可以变得更具可读性和可靠性:
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 或更高版本中使用自动资源管理。
如标题所述,在重用 FileOutputStream 变量时是否应该关闭流?例如,在下面的代码中,我应该在分配新文件之前调用 outfile.close()
吗?为什么?
谢谢:)
FileOutputStream outfile = null;
int index = 1;
while (true) {
// check whether we should create a new file
boolean createNewFile = shouldCreateNewFile();
//write to a new file if pattern is identified
if (createNewFile) {
/* Should I close the outfile each time I create a new file?
if (outfile != null) {
outfile.close();
}
*/
outfile = new FileOutputStream(String.valueOf(index++) + ".txt");
}
if (outfile != null) {
outfile.write(getNewFileContent());
}
if (shouldEnd()) {
break;
}
}
try {
if (outfile != null) {
outfile.close();
}
} catch (IOException e) {
System.err.println("Something wrong happens...");
}
YES. 一旦你完成了一个文件(流),你应该总是关闭它。这样分配给文件(流)的资源将被释放给操作系统,如文件描述符、缓冲区等。
Java 文档 FileOutputStream.close()
Closes this file output stream and releases any system resources associated with this stream. This file output stream may no longer be used for writing bytes.
未关闭的文件描述符甚至会导致 java 程序中的资源泄漏。 Reference
我认为这里的混淆围绕着“重用”FileOutputStream
的概念。您所做的只是通过将新值与其关联来重新使用 identifier(变量的名称 outfile
)。但这仅对 Java 编译器具有语法意义。名称所指的 object – FileOutputStream
– 被简单地丢弃在地板上,最终将在未指定的稍后时间点被垃圾收集。对曾经引用它的变量做什么并不重要。无论您重新分配它另一个 FileOutputStream
、将其设置为 null
还是让它超出范围都是一样的。
调用close
显式将所有缓冲数据刷新到文件并释放相关资源。 (垃圾收集器也会释放它们,但你不知道这会在什么时候发生。)请注意 close
也可能会抛出 IOException
所以你知道操作的时间点真的很重要尝试过,只有在显式调用该函数时才会这样做。
即使没有自动资源管理,或 try-with-resources(见下文),您的代码也可以变得更具可读性和可靠性:
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 或更高版本中使用自动资源管理。