Java BufferedWriter close()

时间:2010-06-02 18:26:12

标签: java file-io bufferedwriter

假设我有以下代码片段:

operation1();
bw.close();
operation2();

当我从代码中调用BufferedReader.close()时,我假设我的JVM进行系统调用,以确保缓冲区已刷新并写入磁盘。我想知道close()是否等待系统调用来完成其操作,或者是否继续operation2()而不等待close()完成。

要重新解释我的问题,当我operation2()时,我可以假设bw.close()已成功完成吗?

8 个答案:

答案 0 :(得分:5)

  

当我执行operation2()时,我可以假设bw.close()已成功完成吗?

答案 1 :(得分:4)

  

关闭水流,先冲洗它。关闭流后,进一步的write()或flush()调用将导致抛出IOException。但是,关闭先前关闭的流无效。

虽然documentation没有特别说明,但我认为此调用会阻止直到完成。事实上,我很确定java.io包中没有任何内容是无阻塞的。

答案 2 :(得分:4)

java.io.BufferedReader.close()的JavaDoc完全来自合同,如果符合java.io.Reader的话。

Doc说:

  

关闭流并释放与其关联的所有系统资源。关闭流后,进一步的read(),ready(),mark(),reset()或skip()调用将抛出IOException。关闭之前关闭的流无效。

虽然在文件系统完成之前没有明确声明阻塞,但使用BufferedReader的同一个实例,如果close()返回,则所有其他操作都会抛出异常。尽管可以看出JavaDoc在操作完成时有些模糊,但如果文件系统刷新和关闭在此方法返回时未完成,则会违反合同的精神并成为Java中的错误(实现或文档)。

答案 3 :(得分:2)

NO!由于以下原因,您无法确定:

BufferedWriter是另一个Writer的包装器。 BufferedWriter的close()只传播到底层的Writer。

如果这个底层Writer是一个OutputStreamWriter,并且如果OutputStream是一个FileOutputStream,那么close将发出一个系统调用来关闭文件句柄。

你甚至可以完全自由地使用一个Writer,其中close()是noop,或者close是非阻塞实现的,但是当只使用java.io中的类时,情况绝对不是这样。

答案 4 :(得分:1)

Writer(或BufferedWriter)是一个黑盒子,它在某处写入一串字符,而不一定写入磁盘。对close() 的调用必须(通过方法合同)在关闭之前刷新其缓冲的内容,并且应该(通常)在完成所有“基本”工作之前阻塞。但这取决于实现和环境(例如,您无法了解Java层下面的缓存)。在Java编写器本身要完成的工作的哪些方面(例如:使系统调用写入磁盘,在FileWriter或akin的情况下,并关闭文件句柄),是的,你可以假设当{{ 1}}返回它已完成所有工作。

答案 5 :(得分:1)

通常,对于任何i / o操作,即使在write()之后,您也无法对close操作完成后发生的事情做出假设。 delivery的概念是相对于媒介的主观概念。

例如,如果writer表示TCP连接,然后客户端和服务器之间的数据丢失怎么办?或者,如果内核将数据写入磁盘,但驱动器在物理上无法写入,该怎么办?或者,如果作者代表在途中被射击的载体鸽?

此外,想象一下当写入无法确认端点已接收到数据时的情况(读取:udp / datagrams)。在这种情况下,阻止政策应该是什么?

答案 6 :(得分:1)

缓冲区已刷新到操作系统,文件句柄已关闭,因此所需的Java操作已经完成。

但是操作系统会将写入缓存或排队到实际磁盘,管道,网络等等 - 无法保证物理写入已完成。 FileChannel.force()为本地磁盘上的文件提供了一种方法:参见Javadoc。

答案 7 :(得分:0)

是的, 如果 您到达operation2();,则必须完全关闭该流。但是,close() throws IOException,您甚至可能无法访问operation2();。这可能是您期望的行为,也可能不是。