假设我有以下代码片段:
operation1();
bw.close();
operation2();
当我从代码中调用BufferedReader.close()
时,我假设我的JVM进行系统调用,以确保缓冲区已刷新并写入磁盘。我想知道close()
是否等待系统调用来完成其操作,或者是否继续operation2()
而不等待close()
完成。
要重新解释我的问题,当我operation2()
时,我可以假设bw.close()
已成功完成吗?
答案 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();
。这可能是您期望的行为,也可能不是。