8

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

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

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

4

1 回答 1

13

BufferedOutputStream在 java 中有一个缓存,FileChannel但没有。

但是,FileChannel确实有操作系统级缓存。其中与/.force()相同。fsyncfdatasync

在 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 }

如果您想了解更多操作系统在此级别的工作原理,请阅读此博客。

于 2011-01-20T02:12:38.273 回答