FileChannel#force 和缓冲

发布于 2024-10-13 02:12:15 字数 659 浏览 1 评论 0原文

我现在想澄清一下,并在 FileOutputStream 和 FileChannel 之间画出一些相似之处。

首先,使用标准 Java io 写入文件的最有效方法似乎是使用用 BufferedOutputStream 包装的 FileOutputStream。因为当内部缓冲区溢出时它会自动刷新。能够方便地进行单次写入(单字节、浮点数等)以及数组写入,并且不用担心速度。您永远不应该忘记的唯一一件事是关闭它(以执行最终刷新)。使用 BufferedOutputStream 包装器的好处是显而易见的,并且对每个人来说都是必须(我希望如此)。

现在介绍 FileChannel。 FileChannel 有force 方法,它相当于FileOutputStream 中的flush,不是吗? 而且javadocs 明确指出,您应该使用它来确保对目标文件进行了更改。但是,如果没有“BufferedFileChannel”包装器,我不明白何时以及为什么应该使用它。 也就是说,FileChannel的缓冲在哪里?它是否像 BufferedOutputStream 一样自动隐藏在 FileChannel 本身中?如果不是,那么我到底为什么需要强制方法,因为没有什么可以强制的(使用写入方法后所有更改都已应用到文件)并且我必须自己实现缓冲吗?

I would like to make it clear and draw some parallels between FileOutputStream and FileChannel right now.

So first of all, it seems like the most efficient way to write file with standart Java io is to use FileOutputStream which is wrapped with BufferedOutputStream. Because it automatically flushes, when the internal buffer is overflowed. It is convenient to be able to do single writes (single bytes, floats, etc.) as well as array ones and to be not worried about speed. The only thing you should never forget is to close it (to perform the final flush). Benefits of using BufferedOutputStream wrapper are evident and must have for everyone (I hope).

Now about FileChannel. FileChannel has force method, which is an equivalent to flush in FileOutputStream, isn't it? And javadocs clearly say, that you should use it to be sure that your changes have been made to the target file. But, I don't understand when and why should I use it, if there is no "BufferedFileChannel" wrapper. In other words, where is buffering for FileChannel? Is it automatic and hidden in FileChannel itself like in BufferedOutputStream? If not, then why on earth would I need force method, since there is nothing to force (all changes are already applied to file after using write method) and do I have to implement buffering by myself?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(1

邮友 2024-10-20 02:12:15

BufferedOutputStream 在 java 中具有缓存,而 FileChannel 则没有。

但是,FileChannel 确实具有操作系统级缓存。其中.force()fsync/ fdatasync

在 OpenJDK 6 中 src/solaris/native/sun/nio/ch/FileChannelImpl.c

  157 JNIEXPORT jint JNICALL
  158 Java_sun_nio_ch_FileChannelImpl_force0(JNIEnv *env, jobject this,
  159                                        jobject fdo, jboolean md)
  160 {
  161     jint fd = fdval(env, fdo);
  162     int result = 0;
  163 
  164     if (md == JNI_FALSE) {
  165         result = fdatasync(fd);
  166     } else {
  167         result = fsync(fd);
  168     }
  169     return handle(env, result, "Force failed");
  170 }

阅读 这个博客如果你想了解更多操作系统在这个级别是如何工作的。

BufferedOutputStream have a cache in java, which FileChannel do not.

However, FileChannel do have OS-Level cache. In which .force() is the same as fsync / fdatasync.

In OpenJDK 6 src/solaris/native/sun/nio/ch/FileChannelImpl.c

  157 JNIEXPORT jint JNICALL
  158 Java_sun_nio_ch_FileChannelImpl_force0(JNIEnv *env, jobject this,
  159                                        jobject fdo, jboolean md)
  160 {
  161     jint fd = fdval(env, fdo);
  162     int result = 0;
  163 
  164     if (md == JNI_FALSE) {
  165         result = fdatasync(fd);
  166     } else {
  167         result = fsync(fd);
  168     }
  169     return handle(env, result, "Force failed");
  170 }

Read this blog if you want to know more how OS works in this level.

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