FileChannel#强制和缓冲

时间:2011-01-20 01:13:57

标签: java buffering filechannel

我想说清楚,并立即在FileOutputStream和FileChannel之间绘制一些相似之处。

首先,看起来使用标准Java io编写文件的最有效方法是使用包含BufferedOutputStream 的FileOutputStream。因为它会在内部缓冲区溢出时自动刷新。能够进行单次写入(单字节,浮点数等)以及数组写入并且不担心速度是很方便的。你唯一不应该忘记的是关闭它(进行最后的冲洗)。使用BufferedOutputStream包装器的好处很明显,必须适合所有人(我希望)。

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

1 个答案:

答案 0 :(得分:9)

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 }

如果您想了解操作系统在此级别中的工作原理,请阅读this blog