Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileChannel#force and buffering

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?

like image 831
Alexander Shukaev Avatar asked Jan 20 '11 01:01

Alexander Shukaev


1 Answers

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.

like image 153
J-16 SDiZ Avatar answered Sep 23 '22 02:09

J-16 SDiZ