1. Клас OutputStream
З потоками введення ми щойно розібралися. Настав час поговорити про потоки виведення.
Клас OutputStream є батьківським класом для всіх класів, які підтримують байтове виведення. Це абстрактний клас, який сам нічого не робить: для цього він має класи-спадкоємці на всі випадки життя.
Складнувато звучить. Простіше кажучи, цей клас оперує байтами, а не, наприклад, символами чи іншими типами даних. А те, що він абстрактний, означає, що ми зазвичай використовуємо не його, а один із його класів-спадкоємців. Наприклад, FileOutputStream та подібні до нього.
Але повернемося до класу OutputStream. У цього класу є методи, які мають реалізовувати всі його класи-спадкоємці. Ось основні з них:
| Методи | Опис |
|---|---|
|
Записує один байт (не int) в потік. |
|
Записує масив байт у потік |
|
Записує частину масиву байт у потік |
|
Записує в потік усі дані, які зберігаються у буфері |
|
Закриває потік |
Під час створення об’єкта класу-спадкоємця InputStream зазвичай вказується об’єкт-джерело, з якого InputStream читає дані. Під час створення об’єкта класу-спадкоємця OutputStream також зазвичай вказується цільовий об’єкт або цільовий потік, в який будуть записуватися дані.
Коротко пройдемося всіма методами класу OutputStream:
Метод write(int b)
Цей метод записує в потік виведення один байт (не int). Передане значення приводиться до типу байт, три перші байти відкидаються.
Метод write(byte[] buffer)
Записує в потік виведення переданий масив байтів. Все.
Метод write(byte[] buffer, int offset, int length)
Записує в потік виведення частину переданого масиву байтів. Змінна offset задає номер першого елемента масиву, length— довжина фрагмента, що записується.
Метод flush()
Метод flush() використовується, щоб примусово записати у цільовий потік дані, які можуть кешуватися в поточному потоці. Актуально у разі використання буферизації та/або кількох об’єктів потоків, організованих у ланцюжок.
Метод close()
Записує в цільовий об’єкт усі незаписані дані. Метод close() можна не викликати, якщо ви використовуєте try-with-resources.
Приклад — копіювання файлу
| Код | Примітка |
|---|---|
|
InputStream для читання з файлуOutputStream для запису у файлБуфер, в який ми будемо зчитувати дані Поки дані присутні в потоці Зчитуємо дані в буфер Записуємо дані з буфера у другий потік |
2. Клас Writer
Клас Writer — це повний аналог класу OutputStream, і знову тільки з однією відмінністю: він працює із символами, char, замість байт.
Це абстрактний клас: об’єкти класу Writer не можна створити. Його основна мета — бути єдиним батьківським класом для сотень класів-спадкоємців і задати для них загальні методи роботи з символьними потоками.
Методи класу Writer (і всіх його класів-спадкоємців):
| Методи | Опис |
|---|---|
|
Записує один символ (не int) в потік. |
|
Записує масив символів у потік |
|
Записує частину масиву символів у потік |
|
Записує рядок у потік |
|
Записує частину рядка у потік |
|
Записує в потік усі дані, які зберігаються у буфері |
|
Закриває потік |
Методи дуже схожі на методи класу OutputStream, тільки працюють із символами замість байт.
Короткий опис методів:
Метод write(int b)
Цей метод записує в потік виведення один символ char (не int). Передане значення приводиться до типу char, два перші байти відкидаються.
Метод write(char[] buffer)
Записує в потік виведення переданий масив символів.
Метод write(char[] buffer, int offset, int length)
Записує в потік виведення частину переданого масиву символів. Змінна offset задає номер першого елемента масиву, length — довжина фрагмента, що записується.
Метод write(String str)
Записує в потік виведення переданий рядок.
Метод write(String str, int offset, int length)
Записує в потік виведення частину переданого рядка: рядок перетворять на масив символів. Змінна offset задає номер першого елемента масиву, length — довжина фрагмента, що записується.
Метод flush()
Метод flush() використовується, щоб примусово записати у цільовий потік дані, які можуть кешуватися в поточному потоці. Актуально у разі використання буферизації та/або кількох об’єктів потоків, організованих у ланцюжок.
Метод close()
Записує в цільовий об’єкт усі незаписані дані. Метод close() можна не викликати, якщо ви використовуєте try-with-resources.
Приклад програми, яка копіює текстовий файл:
| Код | Примітка |
|---|---|
|
Reader для читання з файлуWriter для запису у файлБуфер, в який будемо зчитувати дані Поки дані є в потоці Читаємо дані у буфер Записуємо дані з буфера у другий потік |
Клас StringWriter
Є ще один цікавий клас-спадкоємець від класу Writer — це StringWriter. У ньому знаходиться рядок, що змінюється, — об’єкт StringBuffer. І щоразу, коли ви щось «пишете» в об’єкт StringWriter, текст просто додається у внутрішній буфер.
Приклад:
| Код | Примітка |
|---|---|
|
Створюється цільовий символьний потік StringWriterРядок пишеться в буфер всередині StringWriterРядок пишеться в буфер всередині StringWriterПеретворюємо вміст об’єкта до рядка |
У цьому випадку клас StringWriter — це, по суті, обгортка над класом StringBuffer, проте клас StringWriter — це спадкоємець класу-потоку Writer, і він може використовуватися в ланцюжках із об’єктів-потоків. Доволі корисна властивість на практиці.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ