FileReader и BufferedReader — два класса, которые могут считывать символы из входного потока. В этом туториале мы с вами рассмотрим различия между ними. Класс FileReader предназначен для чтения символьного потока из файла. К сожалению, он может читать файл только посимвольно, и каждый раз, когда мы вызываем его метод read(), он напрямую обращается к файлу на жестком диске, чтобы прочитать из него ровно один символ. В результате FileReader — очень медленный и неэффективный способ чтения символов из файлов. Кроме того, FileReader не может читать символы ни из каких типов потоков входных данных, кроме файлов. FileReader имеет три конструктора: FileReader(File file): получает в качестве аргумента экземпляр файла FileReader(FileDescriptor fd): получает в качестве аргумента дескриптор файла FileReader(String fileName): получает в качестве аргумента имя файла (включая его путь) Каждый раз, когда мы вызываем метод read(), он возвращает целое число, представляющее значение символа в формате Unicode, который был прочитан из файла, или -1, если достигнут конец символьного потока. Давайте посмотрим на использование FileReader в коде примера, в котором мы будем считывать символы из текстового файла, содержащего всего одну строку “qwerty”: В приведенном выше коде мы приводим возвращаемое значение из метода read() к типу char, а затем добавляем его в строку результата. Класс BufferedReader создает буфер для хранения данных из символьного потока. Более того, входной поток может быть файлом, консолью, строкой или любым другим типом символьного потока. Его конструктор требует в качестве входного символьного потока объект типа Reader. Следовательно, мы можем передать в качестве входного потока для чтения символов в BufferedReader любой класс, реализующий абстрактный класс Reader. Когда мы начинаем читать символы с помощью BufferedReader, он считывает весь блок данных из входного потока и сохраняет его в буфере. После этого, если мы продолжим чтение с помощью BufferedReader, он будет возвращать символы не из исходного потока символов, а из буфера, пока полностью не опустеет. Затем он считает следующий блок данных из входного потока и сохранит его в буфере для дальнейших вызовов операций чтения. Класс BufferedReader уменьшает количество операций чтения, вызываемых над входным потоком, а чтение из буфера обычно происходит намного быстрее, чем доступ к базовому входному потоку. Поэтому BufferedReader обеспечивает более быстрый и эффективный способ чтения символов из входного потока. BufferedReader имеет два конструктора: BufferedReader(Reader in): в качестве аргумента получает поток символьных входных данных (который должен реализовывать абстрактный класс Reader)  BufferedReader(Reader in, int sz): в качестве аргументов получает символьный поток и размер буфера  Если мы вызовем метод read(), он возвращает целое число, представляющее значение символа в формате Unicode, который был прочитан из входного потока. Более того, если мы вызовем метод readLine(), он считает сразу целую строку из буфера и вернет ее как string. Давайте посмотрим на пример использования BufferedReader для чтения символов из текстового файла, содержащего три строки: Приведенный выше тестовый код выполняется без ошибок, а это означает, что BufferedReader успешно читает все три строки текста из файла. BufferedReader гораздо быстрее и эффективнее, чем FileReader поскольку он считывает целый блок данных из входного потока и сохраняет его в буфере для дальнейших вызовов метода чтения, в то время как FileReader должен получать доступ к файлу для считывания каждого символа. Более того, FileReader может читать файл только посимвольно, в то время как BufferedReader имеет такие полезные методы, как readLine(), который может считать из буфера сразу целую строку. И наконец, FileReader может производить чтение только из файла, а BufferedReader может читать из любого типа потока символьных входных данных (файл, консоль, строка и т.д.): FileReader BufferedReader Медленнее и менее эффективен Быстрее и эффективнее Может читать только посимвольно Может читать символы и строки Можно читать только из файла Может читать из любого символьного потока Вам может быть достаточно и FileReader, если вы читаете из небольших файлов, или когда вызовов операции чтения не очень много. Однако для больших файлов или когда нужно выполнять много операций чтения данных, BufferedReader — это лучший вариант. В этом туториале мы с вами рассмотрели различия между FileReader и BufferedReader и когда их следует применять. Как всегда, полный исходный код туториала доступен на GitHub. Уже сегодня вечером состоится открытое занятие, на котором познакомимся с Reactor Kafka. На этом уроке посмотрим, как в java-приложении можно работать с Kafka в реактивном стиле. Разберемся, для чего это может быть полезно и когда стоит использовать.  Зарегистрироваться на открытое занятие можно на странице курса "Java Developer Professional".  Редактор