FileChannel#force и буферизация

Я хотел бы прояснить ситуацию и провести некоторые параллели между FileOutputStream и FileChannel прямо сейчас.

Поэтому, во-первых, кажется, что наиболее эффективный способ написания файла со стандартным Java io - это использование FileOutputStream, который обернут в BufferedOutputStream. Потому что он автоматически сбрасывается, когда внутренний буфер переполняется. Удобно иметь возможность делать одиночные записи (одиночные байты, числа с плавающей запятой и т. Д.), А также массивы и не беспокоиться о скорости. Единственное, что вы никогда не должны забывать, это закрыть его (выполнить последний сброс). Преимущества использования оболочки BufferedOutputStream очевидны и должны быть доступны всем (я надеюсь).

Теперь о FileChannel. FileChannel имеет метод force, который эквивалентен сбросу в FileOutputStream, не так ли? И Javadocs ясно говорят, что вы должны использовать его, чтобы быть уверенным, что ваши изменения были внесены в целевой файл. Но я не понимаю, когда и почему я должен использовать его, если нет оболочки "BufferedFileChannel". Другими словами, где буферизация для FileChannel? Это автоматически и скрыто в самом FileChannel как в BufferedOutputStream? Если нет, то с какой стати мне нужен метод force, так как нет ничего, чтобы форсировать (все изменения уже применяются к файлу после использования метода write), и нужно ли мне самостоятельно выполнять буферизацию?

1 ответ

Решение

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 }

Прочтите этот блог, если вы хотите узнать больше, как ОС работает на этом уровне.

Другие вопросы по тегам