Согласно java-документам,

В общем, Writer немедленно отправляет свой вывод в базовый поток символов или байтов. Если вывод подсказки не требуется, рекомендуется обернуть BufferedWriter вокруг любого Writer, чьи операции write () могут быть дорогостоящими, например FileWriters и OutputStreamWriters. Например,

PrintWriter out = новый PrintWriter (новый BufferedWriter (новый FileWriter ("foo.out")));

буферизует вывод PrintWriter в файл. Без буферизации каждый вызов метода print () приведет к преобразованию символов в байты, которые затем будут немедленно записаны в файл, что может быть очень неэффективным.

Но следующий код выглядит так, как будто FileWriter также буферизует байты перед сбросом в выходной поток.

 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;


 public class TestFileWriter {
 /**
 * @param args
 * @throws IOException 
 */
public static void main(String[] args) throws IOException {
    FileWriter fileWriter= new FileWriter("test.txt");
    File file=new File("test.txt");
    for (int i=0; i<1000; i++) {
        fileWriter.write("a very long string, a very long string, a very long string, a very long string, a very long string\n");
        if(i%50 == 0)
            System.out.print("file size=" +  file.length()+",");

    }
    fileWriter.close();
    System.out.println("file size=" +  file.length());

}

}

Выход :-

размер файла = 0, размер файла = 0, размер файла = 8192, размер файла = 8192, размер файла = 16384, размер файла = 24576, размер файла = 24576, размер файла = 32768, размер файла = 32768, размер файла = 40960, размер файла = 49152, размер файла = 49152, размер файла = 57344, размер файла = 57344, размер файла = 65536, размер файла = 73728, размер файла = 73728, размер файла = 81920, размер файла = 81920, размер файла = 90112, размер файла = 99000

Почему данные не записываются в файл во время записи?

4
Kumaran 2 Май 2014 в 13:33

2 ответа

Лучший ответ

Если вы добавите

fileWriter.flush();

Вы можете видеть, что размеры изменились в каждой строке. Это означает, что происходит буферизация.

Используя отладчик, я отследил это до StreamEncoder, у которого нет источника в Oracle JDK, но он доступен онлайн.

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/sun/nio/cs/StreamEncoder.java

private static final int DEFAULT_BYTE_BUFFER_SIZE = 8192;

private StreamEncoder(OutputStream out, Object lock, CharsetEncoder enc) {
    // some deleted
    if (ch == null) {
        bb = ByteBuffer.allocate(DEFAULT_BYTE_BUFFER_SIZE);
    }
}

Как видите, у кодировщика есть собственный буфер.

Примечание: поскольку это внутренний класс, он может измениться в будущем и может не вести себя таким образом на всех платформах.

6
Peter Lawrey 2 Май 2014 в 10:06

Ваше предположение о FileWriter кажется правильным.

Ссылки:

Конструкторы этого класса предполагают, что кодировка символов по умолчанию и размер байтового буфера по умолчанию приемлемы.

[1] http://docs.oracle.com /javase/6/docs/api/java/io/FileWriter.html

[2] java - Использует ли FileWriter буфер? (действует так же, как в моем примере)

Буферизация применяется к основному потоку записи в Java, а не на уровне FileWriter.

2
Community 23 Май 2017 в 12:24