BufferedWriter

Модуль 1. Java Syntax
24 уровень , 3 лекция
Открыта

Очень часто в программах есть требование быстро писать данные в файл или другие источники. И в таких случаях возникает вопрос: что использовать, какой класс выбрать? Сегодня мы познакомимся с одним из подходящих “кандидатов” на эту роль – классом BufferedWriter.

Для чего нужен BufferedWriter

BufferedWriter – это класс, записывающий буферизированные символы в поток. Он позволяет снизить количество данных, обращенных к физическому носителю. То есть, вместо того, чтобы каждый раз писать отдельный символ, он записывает эти данные в буфер, а после – записывает все эти символы в источник.

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


BufferedWriter(Writter in, int sz)

Здесь первый аргумент конструктора – это поток, приемник, в который будет происходить запись. А значение sz – это как раз определение нового размера буфера.

Также в Java еще есть класс BufferedReader: он используется для буферизованного чтения данных.

Собственно, что это такое – буфер? Давай разбираться на примере из жизни. Буфер — это как корзина или тележка в супермаркете. Вместо того, чтобы идти брать товар, нести на кассу, оплачивать, положить в багажник автомобиля и потом по новой возвращаться за другим, мы можем взять тележку, положить все, что нам нужно и оплатить на кассе. Именно так и работает буфер: он соберет твои данные и потом все возьмет и запишет, вместо того чтобы писать каждый фрагмент отдельно.

Конструкторы и методы класса BufferedWriter

Теперь давай подробнее разберем класс BufferedWriter. Для создания объекта есть два конструктора:


public BufferedWriter(Writer out) 
public BufferedWriter(Writer out, int sz)

Где out в обоих конструкторах – это источник для записи, а sz, как уже упоминалось, – это размер буфера.

Также у класса BufferedWriter есть ряд методов. Часть из них сегодня рассмотрим подробнее:

write(char[] array) Запишет массив char в буфер
write(String s, int off, int len) Запишет часть строки в буфер
append(char c) Запишет символ в буфер
append(CharSequence csq, int start, int end) Запишет часть массива в буфер
newLine() Разделяет строку
flush() сбрасывает поток

Напишем программу, которая будет записывать нам значение в файл. В качестве объекта Writer в конструктор передадим FileWriter. Он используется для записи текстовых файлов и имеет несколько конструкторов для инициализации объектов:

FileWriter(File file)
FileWriter(File file, boolean append)
FileWriter(FileDescriptor fd)
FileWriter(String fileName)
FileWriter(String fileName, boolean append)

Для нашего примера используем конструктор, который принимает имя файла:


try(BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file.txt"))){
	
	String message = "Привет Амиго! Это очень важное сообщение!";
	bufferedWriter.write(message);
	bufferedWritter.flush();
}
catch(IOException ex){
System.out.println(ex.getMessage());
 }

Наш код, используя метод write(String str), запишет сообщения str в файл file.txt.

Есть другие методы для записи:

  • write(char[] array) – принимает и записывает массив char-ов;

  • write(String s, int off, int len) – принимает строку s, off – индекс символа строки, с которого начнется запись, и len – длина строки (подстроки), которая будет записана.


try(BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file.txt"))){
	String message = "Привет, Амиго! Это очень важное сообщение!";
	bufferedWriter.write(message, 0, 12);
 	bufferedWriter.flush();

}catch(IOException ex){
System.out.println(ex.getMessage());
}

Этот код запишет в файл: “Привет, Амиг”, так как мы указали записывать начиная с 0 индекса 12 символов.

В нашем коде еще присутствует try-with resources:


try(BufferedWriter bufferedWritter = new BufferedWriter(new FileWriter("file.txt"))) 

Это значит, что для моего объекта bufferedWriter метод close() вызывается автоматически, так как он реализует интерфейс AutoCloseable.

Метод flush() в коде используется для очистки выходного потока и записи всех буферизированных байтов. Без вызова этого метода запись может не произойти, так как он указывает, что нужно очистить буфер и записать байты из него.

Также в классе BufferedWriter есть такой метод как newLine(), который будет добавлять новую строку к нашему сообщению:


try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file.txt"))) {
        String message = "Привет, Амиго! Это очень важное сообщение!";
        bufferedWriter.write(message, 0, 14);
        bufferedWriter.newLine();
        bufferedWriter.write(message, 15, 27);
    } catch (IOException ex) {
        System.out.println(ex.getMessage());
    }

В файле мы получим:

Привет, Амиго!
Это очень важное сообщение!

Сигнатура метода append() выглядит так:


public Writer append(CharSequence csq, int start, int end)

Используется для добавления csq. Здесь start – это индекс первого символа, а end – это индекс последнего символа строки (подстроки), которую нужно вставить, причем последний символ не будет вставлен.


try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("file.txt"))) {
    String message = "Привет Амиго! Это очень важное сообщение!";
    bufferedWriter.append(message, 0, 7);
    bufferedWriter.flush();
} catch (IOException ex) {
    System.out.println(ex.getMessage());
}

Запустив этот код, ты получишь:

Привет

То есть методом append ты указываешь, какую часть строки добавить в буфер.

Если рассмотреть подробнее разницу между write() и append(), то в принципе они оба делают одну и ту же задачу: записывают значения.

Но все же разница заключается в том, что метод append более новый и принимает в аргумент CharSequence, а так как String — это реализация CharSequence, то в append можно положить и String, и StringBuilder, и StringBuffer. Ну а в метод write() можно только String.

Вот и все! Сегодня мы познакомились с буфером, с тем, как осуществлять буферизированную запись в файл, а также с методами, которыми ты можешь пользоваться для этого.

Комментарии (9)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Олег Уровень 106 Expert
6 июня 2024
Я всё понял!
13 января 2023
" Он позволяет снизить количество данных, обращенных к физическому носителю. " Количество ДАННЫХ он не снижает, снижает только количество обращений. Гугл переводчиком переводили? Исправьте пожалуйста, а то путает и понижает восприятие материала.
Адам Уровень 109
25 июня 2024
Не будь душнилой Заводя
jvatechs Уровень 111 Expert
21 декабря 2022
Если кому-то показался непонятным метод flush(): Буфер — это часть памяти, используемая для хранения потока данных (символов). Иногда эти символы отправляются на устройство вывода (например, монитор) только тогда, когда буфер заполнен или соответствует определенному количеству символов. Это может привести к зависанию вашей системы, если вам нужно отправить на устройство вывода всего несколько символов. Метод flush() немедленно сбрасывает содержимое буфера в выходной поток.
Михаил Уровень 102 Expert
19 июня 2022
"Наш код, используя метод write(String str), запишет сообщения str в файл file.txt." В лекции опечатка... Там в примере переменная message
hidden #3378254 Уровень 25
12 февраля 2024
Имеется в виду аргумент, который передается параметру str, записывается в file.txt
Руслан Шмаков Уровень 108 Expert
10 апреля 2022
а где задачи? 😳
Stas S Уровень 108 Expert
31 марта 2022
Почему в 3 примере (с newLine) мы не используем метод flush() ?
Олег Ошурков Уровень 2 Expert
25 февраля 2022
даешь задачи