JavaRush /Курсы /Java Core /Reader/Writer

Reader/Writer

Java Core
9 уровень , 2 лекция
Открыта

— Привет, Амиго! Сегодня Элли тебе рассказала про паттерн адаптер.

Большинство классов, относящихся к потокам ввода-вывода, реализовано в виде адаптера. Они преобразуют либо равнозначные интерфейсы, либо соединяют их по принципу от простого к сложному.

— А InputStreamReader и BufferedReader – тоже адаптеры? По крайней мере, они очень похожи на них по стилю использования: объект после создания передается в конструктор другого объекта.

— Да, InputStreamReader преобразует интерфейс InputStream к интерфейсу ReaderBufferedReader не адаптер в чистом виде, т.к. разработчики Java решили не выделять его методы в отдельный интерфейс. Но по духу, он стоит очень близко к ним.

Вместо того, чтобы писать 100500 различных классов, разработчики Java написали два десятка адаптеров и разрешили их соединять друг с другом, как программисту захочется.

Такой подход очень удобен. Программист всегда может написать свой класс и/или адаптер, реализовать в нем стандартный интерфейс и включить его в собранную им цепочку объектов-адаптеров.

— Так вот как оно, оказывается, все устроено. Вместо больших сложных классов – цепочки простых объектов и адаптеры. А ты просто создаешь их и соединяешь в правильном порядке!

— И реализовываешь то, чего не хватает.

— Да, я понимаю.

— Но вообще-то я хотел сегодня рассказать тебе про Reader и Writer. Это два абстрактных класса, которые очень похожи на классы InputStream и OutputStream. Но в отличие от них, эти два класса работают с символами. Они читают символы и записывают символы. Они очень удобны при работе с текстовой информацией. Давай посмотрим, какие методы у них есть:

Методы класса Reader Что метод делает
int read(char[] cbuf);
— метод сразу читает много символов в буфер (массив символов), пока буфер не заполнится или не закончатся символы там, откуда он их читает.
Метод возвращает количество реально прочитанных символов (оно может быть меньше длины массива)
int read();
— метод читает один символ и возвращает его как результат. Результат расширяется до int, для красоты. Если доступных символов нет, метод вернет «-1».
boolean ready();
— метод возвращает true если есть еще непрочитанные символы для методов read
void close();
— метод «закрывает» поток, вызывается после окончания работы с потоком.
Объект выполняет служебные операции, связанные с закрытием файла на диске и т.д.
Из потока больше нельзя читать данные.

— Оказывается, благодаря методу read(char[] cbuf) из Reader’а можно читать символы целыми блоками, а не по одному символу. Так и быстрее и удобнее.

— Да. А теперь посмотрим, какие методы есть у Writer:

Метод Что метод делает
void write(int c);
— метод записывает один символ. Тип int сужается до char, лишняя часть просто отбрасывается.
void write(char[] cbuff);
— метод записывает массив символов.
void write(String s);
— метод записывает строку. Она просто преобразовывается в массив символов и вызывается второй метод.
void flush();
— если есть данные, которые хранятся где-то внутри и еще не записаны, то они записываются.
void close();
— метод «закрывает» поток – вызывается после окончания работы с потоком.
Объект выполняет служебные операции, связанные с закрытием файла на диске и т.д. В поток больше нельзя писать данные, flush при этом вызывается автоматически.

Важно понять, что Reader и Writer – это абстрактные классы. Они ничего не делают и практически не содержат кода. Все их методы должны будут реализовываться в классах, которые будут унаследованы от них. Их же задача – стандартизировать механизм взаимодействия между классами. Разработчикам не нужно изобретать свои стандарты для взаимодействия друг с другом. Гораздо удобнее всем поддерживать несколько базовых стандартов. Тогда классы, написанные разными программистами, смогут легко взаимодействовать не только с классами, написанными разработчиками Java, но и с классами других программистов.

Стандарты – великая сила.

— Согласен. Поддержка общих стандартов – благо для всех.

Комментарии (155)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Anonymous #3585174 Уровень 33
8 сентября 2025
like
Raizly Уровень 34
10 января 2025
"Вместо того, чтобы писать 100500 различных классов, разработчики Java написали два десятка адаптеров и разрешили их соединять друг с другом, как программисту захочется." Для опытных программистов это возможно и плюс, но для тех, кто изучает язык это довольно сложно постигается.
Денис Кокшаров Уровень 32
17 марта 2025
Для опытных программистов это возможно и плюс, но для тех, кто изучает язык это довольно сложно постигается. снег выпадает зимой и он холодный, редко выпадает летом и часто становится льдом или водой.
{Java_Shark} Уровень 36
5 декабря 2024
++
Денис Кокшаров Уровень 32
17 марта 2025
++Java_Shark
16 июня 2025
++(Денис Кокшаров++(Java_Shark++))
Евгений Уровень 37
21 июня 2025
++(Дмитрий Максимов++(Денис Кокшаров++(Java_Shark++)))
invoker main Уровень 42
6 октября 2025
++(invoker main++(Дмитрий Максимов++(Денис Кокшаров++(Java_Shark++))))
Максим Li Уровень 40
6 апреля 2024
6.04.2024
Long_byte Уровень 43
21 марта 2024
черт побери теперь я начинаю понимать эти строки new BufferedReader(new InputStreamReader(System.in)) если я правильно понял бавередридер обертка для инпутстримридер а инпутстримридер адаптер для систем.ин который обьект InputStream преобразовывает в обьект Reader
YUREC Уровень 36
8 марта 2024
Ты : как же дорешать задачи по крудам с прошлого лвла... Лекция : Оказывается, благодаря методу read(char[] cbuf) из Reader’а можно читать символы целыми блоками, а не по одному символу. Так и быстрее и удобнее.🤡
12 февраля 2024
можно ли назвать BufferedReader оберткой?
Андрей Уровень 51
19 августа 2024
можно но не стоит. Баферет Ридер очень обидчивый. Подберите более вежливое обращение. я бы рекомендовал "Облачение"
Dmitriy Kvitka Уровень 31
7 февраля 2024
До сих пор не понял применительность void flush(); Обязательно его использовать или в качестве хорошего тона, или только там, где есть уверенность/подозрение в том, что данные могут "подвиснуть на перевалочном пункте"?
YUREC Уровень 36
8 марта 2024
тоже не понял в каких случаях этот flush применять
ВК Уровень 36
11 декабря 2024
Применять flush нужно если вам прямо в процессе работы с файлом, но ещё до его закрытия, нужна уверенность в том, что данные которые вы писали в его уже реально записаны на диск, а не накопились где-то в буфере и ждут пока накопится достаточно или вызова close. Например, если вы записываете что-то в файл с логом событий и смотрите этот файл внешними средствами, вам бы, возможно, хотелось видеть записи об этих событиях сразу, а не только когда ваша программа закроет поток, пишущий в лог-файл.
19 января 2024
Вижу здесь много людей не поняли тему и мне будет полезно попытатся обьяснить ее другим, поэтому смотрите. Простой пример. Мы можем написать
 
new InputStreamReader(System.in);
 
потому что System.in имеет тип InputStream и конструктор InputStreamReader'а принимает InputStreamы. InputStreamReader унаследует Reader и переопределяет его методы вызывая методы их у System.in который InputStream. Так вот в этом и есть вся суть адаптера. Мы через клас-наследник одного класса/интерфейса обращаемся к обьекту другого(который в нем хранится). Что я понял с этой лекции: 1)Благодаря адаптерам можно строить такие цепочки как:
 
new BufferredReader(new InputStreamReader(System.in));
 
чтобы добавлять потокам возможностей и удобнее их использовать. 2. Когда говорили про стандартизацию, я думаю имелось в виду что, например благодаря тому, что уже существуют методы для работы с Reader, Writer Input/OutputStream мы можем просто унаследовать наш класс от одного из них и другие классы смогут его использовать как обычный Ридер(Райтер,...). Если бы не стандартизация то пришлось бы писать новый метод для каждого такого класса, что менее удобно; 3)Нам зачем то показали методы которые до этого заставляли использовать.
7 ноября 2024
это лучшее объяснение, что я видел, спасибо:)
Роман Уровень 33
28 ноября 2023
Чем дальше иду, тем сложнее темы и раскрываются все хуже и хуже. Тупо не лекции,а пустышки. Я думал смысл ресурса в том, чтобы давать основу и задачи, а нам решать задачи и расширять базу знаний. Но по итогу просто эти лекции скипаются и такую же точно информацию приходится находить в других источниках. Если первый блок 20 уровневый еще как-то терпимо был, то кор - это просто плевки в воду бесполезные. Что читал, что не читал - 0 смысла просто. Спасибо, как говорится, зов души вырвался. P.S. не удивительно что из реальных историй большинство бросают джавараш после 20 уровня и мало кто доходит до хотя бы 40. Обычно ссылаются что учащиеся не дотянули или не дотерпели,а по факту с таким обучением это превращается в пустую трату времени)
Andrey Vysotsky Уровень 32
27 марта 2024
по поводу консистентности образовательного проыесса согласен, и лекции в джавакор действительно не о чем. Олнако если в 16 уровне синатксиса у меня задымился мозг и я задачи решал вообще не понимая что я делаю, то все задачи в прошлой теме я знал как решить просто прочитав условия, а лекции вызывали только мысль "это я и так знаю, чтото интересное будет?" т е на удивление, резульиат есть
ВК Уровень 36
11 декабря 2024
Загадка бросивших на уровне 20+ оказалась нехитрой) Но мы же никому не скажем, правда?
Antariko Уровень 8
3 февраля 2025
Лично мне ДжаваРаш дает структурированность. Что после чего изучается + задачки + коммьюнити. А если что-то совсем непонятно и даже в комментах объясняют не очень - есть нейронки) А уж они то могут объяснить на любой вкус и цвет.