Дуже часто у програмах є вимога швидко писати дані у файл чи інші джерела. І в таких випадках постає питання: що використати, який клас обрати? Сьогодні ми познайомимося з одним із придатних “кандидатів” на цю роль – класом 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, 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, запише повідомлення 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.
Ось і все! Сьогодні ми ознайомилися з буфером, із тим, як здійснювати буферизований запис у файл, а також із методами, якими ти можеш користуватися для цього.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ