— І це знову я.

— Привіт, Еллі!

— Сьогодні я хочу тобі докладно розповісти про BufferedReader і BufferedWriter.

— Так ти вже мені розповідала про них. Ну, нічого там складного немає.

— Ок. Розкажи, як працює BufferedReader.

BufferedReader — це як перехідник у розетці зі 110 до 220 вольт.

У конструктор об'єкта BufferedReader обов'язково потрібно передати об'єкт Reader, з якого він читатиме дані. Об'єкт BufferedReader читає з Reader 'а дані великими шматками і зберігає їх у себе всередині буфера. Тому читання з пари BufferedReader+Reader швидше, ніж прямо з Reader.

— Правильно. А BufferedWriter?

— Тут також усе просто. Коли ми пишемо в FileWriter, наприклад, дані відразу записуються на диск. Якщо ми часто пишемо невеликі дані, відбувається багато звернень до диска, що уповільнює роботу програми. А якщо ми використовуємо BufferedWriter в якості « перехідника», то операція запису на диск пришвидшиться. BufferedWriter, при записі в нього, зберігає передані дані у внутрішньому буфері, а коли буфер заповнюється – пише дані у Writer одним великим шматком. Це набагато швидше.

— Гм. Все вірно. А що ти забув?

— Після закінчення запису у об'єктаBufferedWriter треба викликати метод flush(), щоб він записав дані з буфера в Writer, які ще не записані, т.е. е. буфер не заповнений до кінця.

— А крім того?

— А крім того, поки буфер ще не записаний у Writer, дані можна видалити та/або замінити на інші.

— Аміго! Я вражена! Ти просто експерт. Добре, тоді я розповім тобі про нові класи: ByteArrayStreamPrintStream.

Отже, ByteArrayInputStream і ByteArrayOutputStream.

Ці класи по суті чимось схожі на StringReader і StringWriter. Тільки StringReader читав символи (char) з рядка (String), а ByteArrayInputStream читає байти з масиву байт (< b>ByteArray).

StringWriter писав символи (char) у рядок, а ByteArrayOutputStream пише байти в масив байт у нього всередині. При записі в StringWriter рядок усередині нього подовжувався, а при записі в ByteArrayOutputStream його внутрішній масив байт теж динамічно розширюється.

Ось приклад, який виводить у консоль отриманий рядок:

Читання з об'єкта reader та запис в об'єкт writer:
public static void main (String[] args) throws Exception
{
 String test = "Hi!\n My name is Richard\n I'm a photographer\n" ;
 StringReader reader = новий StringReader(test);

 StringWriter writer = new StringWriter();

 executor(reader, writer);

 String result = writer.toString();

 System.out.println("Результат: "+result);
}

public static void executor(Reader reader, Writer writer) throws Exception
{
 BufferedReader br = новий BufferedReader(reader);
String line;
 while ((line = br.readLine()) != null) {
    writer.write(line + '\n');
 }
}

Ось як він виглядатиме, якщо тут працювати не з символами, а з байтами:

Читання з об'єкта InputStream та запис в об'єкт OutputStream:
public static голосовий ключ (String[] args) throws Exception
{
 String test = "Hi!\n My name is Richard\n I'm a photographer\n";
 InputStream inputStream = новий ByteArrayInputStream(test.getBytes());

 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

 executor(inputStream, outputStream);

 String result = new String(outputStream.toByteArray());
 System.out.println("Результат: "+result);
}

public static void executor(InputStream inputStream, OutputStream outputStream) throws Exception
{
 BufferedInputStream bis = новий BufferedInputStream(inputStream) ;
 while (bis.available() > 0)
 {
  int data = bis.read();
  outputStream.write(data);
 }
}

Тут все аналогічно прикладу вище. Замість String - ByteArray. Замість Reader – InputStream, замість Writer – OutputStream.

Єдині ще два моменти – це перетворення рядка на масив байт і назад. Як бачиш, це робиться досить нескладно:

Перетворення рядка на масив байт і назад
public static void main (String[] args) throws< /strong> Exception
{
 String test = "Hi!\n My name is Richard\n I'm a photographer\n" ;
 byte[] array = test.< strong>getBytes();

 String result = new String(array) ;
 System.out.println("Результат: "+result);
}

Щоб отримати байти, які вже додані до ByteArrayOutputStream, потрібно викликати метод toByteArray().

— Ага. Аналогія з StringReader/StringWriter є досить сильною, особливо коли ти мені її показала. Дякую, Еллі, справді цікавий урок.

— Куди це ти поспішаєш? Я маю ще невеликий подарунок – хочу розповісти тобі про клас PrintStream.

— PrintStream? Вперше чую про такий клас.

— Ага. Особливо, якщо не брати до уваги, що ти ним користуєшся з першого дня, коли ти почав вивчати Java. Пам'ятаєш System.out? так ось – System.out – це статична змінна класу System типу… PrintStream! Саме звідти ростуть ноги всіх цих print, println тощо.

— Ого. Як цікаво. Я жодного разу і не замислювався. Розкажи докладніше.

— Гуд. Тоді слухай. Клас PrintStream був придуманий для читального виведення інформації. Він практично весь складається з методів print і println. таблицю:

Методи Методи
void print(boolean b) void println(boolean b)
void print(char c) void println(char c)
void print(int c) void println(int c)
void print(long c) void println(long c)
void print(float c) void println(float c)
void print(double c) void println(double c)
void print(char[] c) void println(char[] c)
void print(String c) void println(String c)
void print(Object obj) void println(Object obj)
  void println()
PrintStream format (String format, Object ... args)
PrintStream format (Locale l, String format, Object ... args)

Також є кілька методів format, щоб можна було виводити дані на основі шаблону. Приклад:

Перетворення рядка на масив байт і назад
String name = "Kolan";
int age = 25;
System.out.format("My name is %s. My age is %d< /span>.", name, age);
Виведення на екран:
My name is Kolan. My age is 25.

— Ага, пам'ятаю, ми вже колись розбирали метод format у класу String.

— На цьому все.

— Дякую, Еллі.