Java BufferedWriter 关闭()

发布于 2024-09-03 13:10:59 字数 365 浏览 6 评论 0原文

假设我有以下代码片段:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

那些过往 2024-09-10 13:10:59

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

是的

when I do operation2(), can I assume that bw.close() has completed successfully?

Yes

情泪▽动烟 2024-09-10 13:10:59

关闭流,首先刷新它。一旦流被关闭,进一步的 write() 或flush() 调用将导致抛出 IOException 。但是,关闭之前关闭的流没有任何效果。

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

Close the stream, flushing it first. Once a stream has been closed, further write() or flush() invocations will cause an IOException to be thrown. Closing a previously-closed stream, however, has no effect.

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.

坏尐絯℡ 2024-09-10 13:10:59

如果满足 java.io.Reader,则 java.io.BufferedReader.close() 的 JavaDoc 完全取自合同。

医生说:

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

虽然这没有明确声明在文件系统完成之前阻塞,但对于 BufferedReader 的同一实例,如果 close() 返回,所有其他操作都将引发异常。尽管 JavaDoc 对于操作何时完成可能被视为含糊不清,但如果此方法返回时文件系统刷新和关闭未完成,则将违反契约精神并成为 Java 中的错误(实现或文档)。

The JavaDoc for the java.io.BufferedReader.close() is taken exactly from the contract if fulfills with the java.io.Reader.

The Doc says:

Closes the stream and releases any system resources associated with it. Once the stream has been closed, further read(), ready(), mark(), reset(), or skip() invocations will throw an IOException. Closing a previously closed stream has no effect.

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 if close() 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).

辞别 2024-09-10 13:10:59

不!您无法确定,原因如下:

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.

何以畏孤独 2024-09-10 13:10:59

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

A Writer (or BufferedWriter) is a black box that writes a stream of characters somewhere, not necessarily to the disk. A call to close() 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 when close() returns it has already done all its work.

辞慾 2024-09-10 13:10:59

一般来说,对于任何 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 you close. The idea of delivery 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?

∞梦里开花 2024-09-10 13:10:59

缓冲区将被刷新到操作系统并关闭文件句柄,因此所需的 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.

虫児飞 2024-09-10 13:10:59

是的,如果您到达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 to operation2();. This may or may not be the behavior that you expect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文