2015-10-14 158 views
4

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

谢谢:)

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..."); 
} 
+1

*“在为其分配新文件之前”* - 是的,您可以将更改保留在缓冲区中,这意味着它们可能不会保存到文件中。您正在使用文件句柄,这是操作系统中有限的资源。您正在JVM中占用资源。你应该随时清理你自己。查看[The try-with-resources Statement](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)以获取更好的解决方案,以处理可关闭的资源 – MadProgrammer

回答

1

我认为这里的困惑围绕着“重新使用”FileOutputStream的概念。你正在做的只是重新使用标识符(名称outfile变量)通过关联一个新值与它。但是这只对Java编译器具有语法意义。名为FileOutputStream对象只是简单地放在地板上,最终将在未指定的时间点进行垃圾回收。不管你用这个曾经提到它的变量做什么都没有关系。无论你重新分配它FileOutputStream,将其设置为null或让它超出范围都是一样的。

调用close明确地将所有缓冲的数据刷新到文件并释放关联的资源。 (垃圾收集器也会释放它们,但是你不知道什么时候会发生这种情况。)请注意,close也可能会抛出一个IOException,所以确实很重要,因为您知道尝试操作的位置,只有在您致电该功能明确。

5

YES。一旦你完成了一个文件(流),你应该总是关闭它。因此,与该文件(流)分配的资源将被释放给操作系统,如文件描述符,缓冲等

Java文档FileOutputStream.close()

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

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

2

即使没有自动资源管理,或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或更高版本中使用自动资源管理。

相关问题