1. Клас InputStreamReader
Ще однією цікавою особливістю потоків є можливість об’єднувати кілька потоків у ланцюжки. Потік може читати дані не лише з джерела даних, яке їх зберігає, але й з іншого потоку.
Це дуже потужний механізм у Java, який дозволив створювати складні сценарії читання даних, з’єднуючи одні потоки з іншими. Виглядає така схема приблизно так:

Коли програма читає дані з потоку даних, він своєю чергою читає їх зі свого джерела даних: іншого потоку даних або з файлу, наприклад.
При цьому кожен потік даних не просто читає і передає дані, а ще може перетворювати їх чи виконувати над ними різні операції. Хорошим прикладом такого «проміжного потоку» даних є клас InputStreamReader.
Ми вже знаємо клас, що називається FileReader, і це Reader, який читає дані з файлу. А звідки читає дані клас InputStreamReader? Правильно: з потоку InputStream.
Щоб створити об’єкт типу InputStreamReader, у нього треба передати об’єкт типу InputStream чи його класу-нащадка. Приклад:
String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);
У класу InputStreamReader є всі методи, які є у класу Reader, причому вони працюють точно так само.
Основна відмінність класів InputStreamReader і, наприклад, FileReader у тому, звідки вони читають дані. FileReader читає дані з файлу (тому він і називається FileReader), а InputStreamReader читає дані з потоку InputStream.
Коли ви читаєте символ із об’єкта FileReader за допомогою методу read(), він своєю чергою читає з файлу на диску два байти і повертає їх вам як char.
Коли ви читаєте символ із об’єкта InputStreamReader за допомогою методу read(), він своєю чергою читає два байти з переданого у нього об’єкта FileInputStream, який своєю чергою читає дані з файлу. Виходить такий ланцюжок викликів методів read().
2. Клас BufferedReader
Є ще один цікавий клас, який ви, найімовірніше, часто використовуватимете — BufferedReader. Це теж «проміжний потік», який читає дані з іншого потоку.
Клас BufferedReader, як видно з його назви, є класом-нащадком від Reader і дозволяє читати символи. Але, що найцікавіше, як джерело даних у нього теж треба передати потік, із якого можна читати символи – потік-нащадок від класу Reader.
У чому ж сенс? На відміну від InputStreamReader’а, клас BufferedReader не перетворює байти на символи: він взагалі нічого не перетворює. Натомість він буферизує дані.

Коли програма читає з об’єкта BufferedReader один символ, він читає зі свого потоку-джерела одразу великий масив символів. І зберігає їх у себе всередині.
Під час читання наступного символу з об’єкта BufferedReader, він просто візьме черговий символ зі свого внутрішнього масиву-буфера і віддасть його, не звертаючись при цьому до потоку-джерела даних. І тільки коли всі символи в буфері закінчаться, він знову прочитає великий масив символів.
Ще у класу BufferedReader є дуже корисний метод — String readLine(), який дозволяє читати дані з потоку-джерела одразу рядками. За допомогою цього методу можна, наприклад, прочитати якийсь файл і вивести його вміст на екран рядок за рядком. Приклад:
Ми спеціально записали код у компактному форматі, щоб ви побачили, як це може бути зручно. Можна записати цей код і трохи більш детально.
|
Створюємо об’єкт FileReader, джерело даних — файл.Створюємо об’єкт BufferedReader, джерело даних — об’єкт FileReader;поки у reader ще є даніПрочитати одну лінію Вивести лінію на екран |
Якщо ви об’єднали кілька потоків у ланцюжок, метод close() достатньо викликати лише в одного з них: він викличе його у свого джерела даних і т.д., поки не дійдуть до фінального потоку з даними.
3. Читання з консолі
І ще один цікавий факт: клас Scanner — це вхідний проміжний потік даних, який читає їх із потоку System.in — теж потоку даних.
Ось два способи читання рядка з консолі:
| Клас Scanner | Класи BufferedReader і InputStreamReader |
|---|---|
|
|
Наш знаменитий System.in — це статична змінна in класу System. Тип її — InputStream, а ім’я — in.
Отже, практично з самого початку вивчення Java на CodeGym ви працюєте з потоками даних і будуєте з них ланцюжки. Тільки тепер ви робитимете це більш усвідомлено.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ