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 на JavaRush. А відтепер ви зможете це робити більш осмислено.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ