Разница 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();
Я понимаю концепцию буферизации данных во-первых, так это означает, что первый пример записывает символы один за другим, а второй сначала буферизирует его в память и записывает один раз?
спасибо за помощь
Ответы
Ответ 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() приведет к преобразованию символов в байты, которые затем будут немедленно записаны в файл, что может быть очень неэффективным.