我需要关闭流吗?

问题描述:

以下示例中是否需要关闭FileOutputStream?为什么?我需要关闭流吗?

FileOutputStream fos = new FileOutputStream("bytes.info"); 
ObjectOutputStream oos = new ObjectOutputStream(fos); 
oos.writeObject(data); 
oos.close(); 
+2

如果你的意思是'OutputStream'那么**是**你绝对会这样做。实际上,你应该总是**使用[try-with-resources](https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)。 –

+0

虽然我建议使用try-with-resources语句,但是'oos.close()'无论如何都会关闭FileOutputStream。 –

+0

@BoristheSpider比为什么这家伙没有关闭它在一篇文章[http://www.ibm.com/developerworks/java/library/j-5things1/index.html?S_TACT=105AGX99&S_CMP=CP] – furry

如果没有抛出异常,则FileOutputStream将被ooo.close()关闭。

writeObject中引发的异常会阻止任何流被关闭。所以close调用应该在最后一块。

还有一个额外的问题,ObjectOutputStream可能会在其构造函数中抛出异常。它将流头写入可能导致异常的构造函数中。在这种情况下,需要关闭FileOutputStream,但不能拨打oos.close(),因为没有提及ObjectOutputStream。所以你真的需要两个独立的电话close,每个流一个,都在最后的块。

使用try-与资源照顾这一切为您:

try(
    FileOutputStream fos = new FileOutputStream("bytes.info"); 
    ObjectOutputStream oos = new ObjectOutputStream(fos) 
) { 
    oos.writeObject(data); 
} 

是的,你需要关闭流。未关闭FileOutputStream会导致已成功写入流中的某些数据无法保存到文件中。如果一个程序打开多个文件流,但不关闭它们会由于本机资源耗尽(同时打开太多文件)而导致失败。

FileOutputStream管理本地资源,由close方法发布。这个类也有一个终结器,它也释放资源。作为释放原生资源的一部分,如果存在任何缓冲数据,流将完成写入。但是,由于JVM并不保证每个对象都会调用终结器,因此如果调用close失败,则会导致保留缓冲区数据不成文的风险。

当然,你必须关闭FileOutputStream中的文件。如果不是有时您保存到文件中的数据可能无法保存,并且在执行程序后最终会得到一个空文件。你可能想使用资源尝试,所以你不必手动关闭它,并可以一次执行异常处理部分。

try (FileOutputStream fos = new FileOutputStream("bytes.info"); 
ObjectOutputStream oos = new ObjectOutputStream(fos));{ 

}catch(){} 

就在,如果你不使用try与资源关闭文件流手动finally块的情况。

FileOutputStream fos = null; 
ObjectOutputStream oos = null; 

try{ 
     fos = new FileOutputStream("bytes.info"); 
     oos = new ObjectOutputStream(fos)); 

     oos.writeObject(data); 
    }catch(){ 
    }finally{ 
     if(fos != null){ 
     fos.close(); 
     } 
     if(oos != null){ 
     oos.close(); 
     } 
    } 

这是必须检查这些文件流是否为空。因为如果它们为空,那么会有另一个错误。仍然最好使用资源尝试。

+1

[关闭](https://docs.oracle.com/javase/7/docs/api/java/io/Closeable.html)'.close()'可以抛出'IOException',所以你的第二块应该以某种方式处理与'fos.close()'的情况下抛出它。 –