Подтвердить что ты не робот

Разница Java между FileWriter и BufferedWriter

Какая разница между ними? Я просто изучаю Java-банкомат, но мне кажется, что я могу записать файл в оба пути (т.е. Я не копировал блок try-catch)

FileWriter file = new FileWriter("foo.txt");
file.write("foobar");
file.close();

и

FileWriter file = new FileWriter("foo.txt");
BufferedWriter bf = new BufferedWriter(file);
bf.write("foobar");
bf.close();

Я понимаю концепцию буферизации данных во-первых, так это означает, что первый пример записывает символы один за другим, а второй сначала буферизирует его в память и записывает один раз?

спасибо за помощь

4b9b3361

Ответ 1

BufferedWriter эффективнее, если вы

  • имеют несколько записей между flush/close
  • записи небольшие по сравнению с размером буфера.

В вашем примере у вас есть только одна запись, поэтому BufferedWriter просто добавляет накладные расходы, которые вам не нужны.

значит ли это, что первый пример записывает символы один за другим, а второй сначала буферизует его в память и записывает один раз

В обоих случаях строка записывается сразу.

Если вы используете только FileWriter, ваши вызовы write (String)

 public void write(String str, int off, int len) 
        // some code
        str.getChars(off, (off + len), cbuf, 0);
        write(cbuf, 0, len);
 }

Это делает один системный вызов для каждого вызова для записи (String).


В тех случаях, когда BufferedWriter повышает эффективность, выполняется несколько небольших операций записи.

for(int i = 0; i < 100; i++) {
    writer.write("foorbar");
    writer.write(NEW_LINE);
}
writer.close();

Без BufferedWriter это может сделать системные вызовы 200 (2 * 100) и записывать на диск, который неэффективен. С BufferedWriter все они могут буферизироваться вместе, и поскольку размер буфера по умолчанию составляет 8192 символа, это становится всего лишь 1 системным вызовом для записи.

Ответ 2

Вы правы. Вот как выглядит метод write() BufferedWriter:

public void write(int c) throws IOException {
    synchronized (lock) {
        ensureOpen();
        if (nextChar >= nChars)
            flushBuffer();
        cb[nextChar++] = (char) c;
    }
}

Как вы видите, он действительно проверяет, заполнен ли буфер (if (nextChar >= nChars)) и очищает буфер. Затем он добавляет новый символ в буфер (cb[nextChar++] = (char) c;).

Ответ 3

BufferedWriter более эффективен. Он сохраняет мелкие записи и записывает в один более крупный фрагмент, если память правильно меня обслуживает. Если вы делаете много мелких записей, я бы использовал BufferedWriter. Как правило, желательно вызвать вызовы записи в ОС, которые медленны, поэтому желательно как можно меньше записей.

Ответ 4

Из спецификации API Java:

FileWriter

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

BufferedWriter

Запись текста в поток вывода символов, буферизация символов, чтобы обеспечить эффективную запись отдельных символов, массивов и строк.

Ответ 5

http://docs.oracle.com/javase/1.5.0/docs/api/java/io/BufferedWriter.html

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

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

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