Java BufferedWriter close()

Java BufferedWriter close(),java,file-io,bufferedwriter,Java,File Io,Bufferedwriter,假设我有以下代码片段: operation1(); bw.close(); operation2(); 当我从代码中调用BufferedReader.close()时,我假设JVM进行了一次系统调用,以确保缓冲区已刷新并写入磁盘。我想知道close() 为了重新表述我的问题,当我执行operation2()时,我是否可以假定bw.close()已成功完成 关闭小溪,先冲洗。关闭流后,进一步的write()或flush()调用将导致引发IOException。但是,关闭以前关闭的流没有效果 虽然

假设我有以下代码片段:

operation1();
bw.close();
operation2();
当我从代码中调用
BufferedReader.close()
时,我假设JVM进行了一次系统调用,以确保缓冲区已刷新并写入磁盘。我想知道
close()

为了重新表述我的问题,当我执行
operation2()
时,我是否可以假定
bw.close()
已成功完成

关闭小溪,先冲洗。关闭流后,进一步的write()或flush()调用将导致引发IOException。但是,关闭以前关闭的流没有效果

虽然没有具体说明什么,但我假设这个调用会一直阻塞到完成。事实上,我非常确定
java.io
包中没有任何东西是非阻塞的

在执行操作2()时,是否可以假定bw.close()已成功完成


是,如果您达到
操作2(),则流必须完全关闭。但是,
close()抛出IOException
,因此您甚至可能无法访问
operation2()。这可能是您期望的行为,也可能不是。

一个
编写器
(或
BufferedWriter
)是一个黑匣子,它将字符流写入某个位置,而不一定写入磁盘。对的调用必须(通过方法契约)在关闭之前刷新其缓冲内容,并且应该(通常)在其所有“基本”工作完成之前阻塞。但这取决于实现和环境(例如,您无法了解Java层下面的缓存)。在Java编写器本身要完成的工作的哪些方面(例如:在FileWriter或类似的情况下,进行系统调用以写入磁盘,并关闭filehandle),是的,您可以假设当
close()
返回时,它已经完成了所有的工作。

用于
Java.io.BufferedReader.close()的JavaDoc如果使用
java.io.Reader
,则完全取自合同

医生说:

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


虽然在文件系统完成之前没有明确的阻塞声明,但是对于相同的
BufferedReader
实例,如果
close()
返回,所有其他操作都将抛出异常。虽然JavaDoc对于操作何时完成可能会被视为模棱两可,但如果此方法返回时文件系统flush和close未完成,则将违反合同精神,并成为Java(实现或文档)中的一个bug。

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

BufferedWriter是另一个写入程序的包装器。BufferedWriter的close()只会传播到底层编写器

如果此基础写入程序是OutputStreamWriter,并且OutputStream是FileOutputStream,则close将发出系统调用以关闭文件句柄


如果close()是一个noop,或者close是非阻塞实现的,那么您甚至可以完全自由地使用Writer,但如果只使用java.io中的类,则情况永远不会如此

通常,对于任何i/o操作,您都不能对
write()
操作完成后发生的情况做出任何假设,即使是在
关闭后。
delivery
的概念是一个相对于媒介的主观概念

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


此外,假设写入无法确认端点已接收数据(读取:udp/数据报)的情况。在这种情况下,阻塞策略应该是什么?

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


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

您是指BufferedWriter,我猜定义为“已成功完成”,在这种情况下,他不会首先“执行操作2()”。@Oscar:原来的单词是“当我执行
操作2()
”。英语不是我的第一语言,但我认为WHEN比IF更重要,在这种情况下,它可能重要,也可能不重要……英语不是我的第一语言。。奥斯卡:我的理解是,在英语中,“如果”一词与“什么时候”一词的含义不同。“何时”更重要,因为这意味着它会发生,这只是时间的问题。“如果”不能保证它会首先发生。这正是我在这里要强调的:
operation2()不是一个简单的“何时”问题。这是一个“如果”。尤其是windows会成为这个问题的受害者——如果你关闭一个文件,然后转身重新打开并读取它,如果你速度太快,你可能无法找回所有字节…@rogerdpack我从1988年开始就在Windows系统周围工作,我从未见过这种情况。看来我错了——我想的情况是,执行fflush不足以让File#stat看到字节(还需要一个fsync)。我看到的其他问题是在网络共享上,