Java BufferedWriter 关闭()
假设我有以下代码片段:
operation1();
bw.close();
operation2();
当我从代码中调用 BufferedReader.close() 时,我假设 JVM 进行了一个系统调用,以确保缓冲区已被刷新并写入磁盘。我想知道 close()
是否等待系统调用完成其操作,或者是否在不等待 close()
的情况下继续进行 operation2()
代码> 完成。
重新表述一下我的问题,当我执行 operation2()
时,我可以假设 bw.close()
已成功完成吗?
Assume that I have the following code fragment:
operation1();
bw.close();
operation2();
When I call BufferedReader.close()
from my code, I am assuming my JVM makes a system call that ensures that the buffer has been flushed and written to disk. I want to know if close()
waits for the system call to complete its operation or does it proceed to operation2()
without waiting for close()
to finish.
To rephrase my question, when I do operation2()
, can I assume that bw.close()
has completed successfully?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
是的
Yes
虽然 文档 确实没有具体说明什么,我假设这个调用确实会阻塞直到完成。事实上,我很确定 java.io 包中没有任何内容是非阻塞的。
Though the documentation does not say anything specifically, I would assume this call does block until finished. In fact, I'm pretty sure nothing in the
java.io
package is non-blocking.如果满足
java.io.Reader
,则java.io.BufferedReader.close()
的 JavaDoc 完全取自合同。医生说:
虽然这没有明确声明在文件系统完成之前阻塞,但对于
BufferedReader
的同一实例,如果close()
返回,所有其他操作都将引发异常。尽管 JavaDoc 对于操作何时完成可能被视为含糊不清,但如果此方法返回时文件系统刷新和关闭未完成,则将违反契约精神并成为 Java 中的错误(实现或文档)。The JavaDoc for the
java.io.BufferedReader.close()
is taken exactly from the contract if fulfills with thejava.io.Reader
.The Doc says:
While this makes no explicit claim of blocking until the file system is complete, with this same instance of
BufferedReader
all other operations will throw an exception ifclose()
returns. Although the JavaDoc could be seen as ambiguous about when the operation completes, if the file system flush and close were not complete when this method returned it would violate the spirit of the contract and be a bug in Java (implementation or documentation).不!您无法确定,原因如下:
BufferedWriter 是另一个 Writer 的包装器。 BufferedWriter 的 close() 只会传播到底层 Writer。
如果这个底层 Writer 是一个 OutputStreamWriter,并且如果 OutputStream 是一个 FileOutputStream,则 close 将发出系统调用来关闭文件句柄。
您甚至可以完全自由地拥有一个 Writer,其中 close() 是一个 noop,或者 close 是非阻塞实现的,但是当仅使用 java.io 中的类时,情况绝不会如此。
NO! You cannot be sure for the following reason:
A BufferedWriter is a Wrapper for another Writer. A close() to the BufferedWriter just propagates to the underlying Writer.
IF this underlying Writer is an OutputStreamWriter, and IF the OutputStream is a FileOutputStream, THEN the close will issue a system call to close the file handle.
You are completely free to even have a Writer where close() is a noop, or where the close is implemented non-blocking, but when using only classes from java.io, this is never the case.
Writer
(或BufferedWriter
)是一个黑匣子,它将字符流写入某处,不一定写入磁盘。调用close()
必须(通过方法契约)在关闭之前刷新其缓冲内容,并且应该(通常)在其所有“必要”之前阻塞工作完成了。但这取决于实现和环境(例如,您无法了解 Java 层以下的缓存)。 Java 编写器本身要完成哪些工作(例如:在 FileWriter 或类似的情况下进行系统调用以写入磁盘,并关闭文件句柄),是的,您可以假设当close()
返回它已经完成了所有工作。A
Writer
(orBufferedWriter
) is a black box that writes a stream of characters somewhere, not necessarily to the disk. A call toclose()
must (by method contract) flush its buffered content before closing, and should (normally) block before all its "essential" work is done. But this would depend on the implementation and the environment (you cannot know about caches that are below the Java layer, for example). In what respects of the work to be done by the Java writer itself (eg: make the system call to write to disk, in the case of a FileWriter or akin, and close the filehandle) , yes, you can assume that whenclose()
returns it has already done all its work.一般来说,对于任何 I/O 操作,您都无法假设
write()
操作完成后发生了什么,即使是在close
后也是如此。传递
的想法是一个相对于媒介的主观概念。例如,如果
writer
代表一个TCP连接,然后数据在客户端和服务器之间丢失怎么办?或者如果内核将数据写入磁盘,但驱动器物理上无法写入怎么办?或者如果作者代表的是一只在途中被射杀的信鸽?此外,想象一下写入无法确认端点已收到数据(读取:udp/数据报)的情况。在这种情况下,封锁政策应该是什么?
In general with any i/o operation you can make no assumptions about what has happened after the
write()
operation completes, even after youclose
. The idea ofdelivery
is a subjective concept relative to the medium.For instance, what if the
writer
represents a TCP connection, and then the data is lost inbetween client and server? Or what if the kernel writes data to a disk, but the drive physically fails to write it? Or if the writer represents a carrier pigeon that gets shot en route?Furthermore, imagine the case when the write has no way of confirming that the endpoint has received the data (read: udp/datagrams). What should the blocking policy be in that situation?
缓冲区将被刷新到操作系统并关闭文件句柄,因此所需的 Java 操作将已完成。
但操作系统将缓存或排队写入实际磁盘、管道、网络等 - 不能保证物理写入已完成。 FileChannel.force() 提供了一种对本地磁盘上的文件执行此操作的方法:请参阅 Javadoc。
The buffer will have been flushed to the operating system and the file handle closed, so the Java operations required will have been completed.
BUT the operating system will have cached or queued the write to the actual disk, pipe, network, whatever - there is no guarantee that the physical write has completed. FileChannel.force() provides a way to do that for files on local disks: see the Javadoc.
是的,如果您到达
operation2();
,流就必须完全关闭。但是,close() 会抛出 IOException
,因此您甚至可能无法到达operation2();
。这可能是也可能不是您期望的行为。Yes, IF you reach
operation2();
, the stream would've had to have been completely closed. However,close() throws IOException
, so you may not even get tooperation2();
. This may or may not be the behavior that you expect.