Как стать автором
Обновить
599.13
OTUS
Цифровые навыки от ведущих экспертов

Разница между FileReader и BufferedReader в Java

Время на прочтение4 мин
Количество просмотров12K
Автор оригинала: Michal Aibin

1. Обзор

FileReader и BufferedReader — два класса, которые могут считывать символы из входного потока.

В этом туториале мы с вами рассмотрим различия между ними.

2. FileReader

Класс FileReader предназначен для чтения символьного потока из файла. К сожалению, он может читать файл только посимвольно, и каждый раз, когда мы вызываем его метод read(), он напрямую обращается к файлу на жестком диске, чтобы прочитать из него ровно один символ. В результате FileReader — очень медленный и неэффективный способ чтения символов из файлов. Кроме того, FileReader не может читать символы ни из каких типов потоков входных данных, кроме файлов.

2.1. Конструкторы

FileReader имеет три конструктора:

  • FileReader(File file): получает в качестве аргумента экземпляр файла

  • FileReader(FileDescriptor fd): получает в качестве аргумента дескриптор файла

  • FileReader(String fileName): получает в качестве аргумента имя файла (включая его путь)

2.2. Что он возвращает

Каждый раз, когда мы вызываем метод read(), он возвращает целое число, представляющее значение символа в формате Unicode, который был прочитан из файла, или -1, если достигнут конец символьного потока.

2.3. Пример

Давайте посмотрим на использование FileReader в коде примера, в котором мы будем считывать символы из текстового файла, содержащего всего одну строку “qwerty”:

@Test
public void whenReadingAFile_thenReadsCharByChar() {
    StringBuilder result = new StringBuilder();

    try (FileReader fr = new FileReader("src/test/resources/sampleText2.txt")) {
        int i = fr.read();

        while(i != -1) {
            result.append((char)i);

            i = fr.read();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    assertEquals("qwerty", result.toString());
}

В приведенном выше коде мы приводим возвращаемое значение из метода read() к типу char, а затем добавляем его в строку результата.

3. BufferedReader

Класс BufferedReader создает буфер для хранения данных из символьного потока. Более того, входной поток может быть файлом, консолью, строкой или любым другим типом символьного потока.

Его конструктор требует в качестве входного символьного потока объект типа Reader. Следовательно, мы можем передать в качестве входного потока для чтения символов в BufferedReader любой класс, реализующий абстрактный класс Reader.

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

Класс BufferedReader уменьшает количество операций чтения, вызываемых над входным потоком, а чтение из буфера обычно происходит намного быстрее, чем доступ к базовому входному потоку. Поэтому BufferedReader обеспечивает более быстрый и эффективный способ чтения символов из входного потока.

3.1. Конструкторы

BufferedReader имеет два конструктора:

  • BufferedReader(Reader in): в качестве аргумента получает поток символьных входных данных (который должен реализовывать абстрактный класс Reader

  • BufferedReader(Reader in, int sz): в качестве аргументов получает символьный поток и размер буфера 

3.2. Что он возвращает

Если мы вызовем метод read(), он возвращает целое число, представляющее значение символа в формате Unicode, который был прочитан из входного потока. Более того, если мы вызовем метод readLine(), он считает сразу целую строку из буфера и вернет ее как string.

3.3. Пример

Давайте посмотрим на пример использования BufferedReader для чтения символов из текстового файла, содержащего три строки:

@Test
public void whenReadingAFile_thenReadsLineByLine() {
    StringBuilder result = new StringBuilder();

    try (BufferedReader br = new BufferedReader(new FileReader("src/test/resources/sampleText1.txt"))) {
        String line;

        while((line = br.readLine()) != null) {
            result.append(line);
            result.append('\n');
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    assertEquals("first line\nsecond line\nthird line\n", result.toString());
}

Приведенный выше тестовый код выполняется без ошибок, а это означает, что BufferedReader успешно читает все три строки текста из файла.

4. В чем разница?

BufferedReader гораздо быстрее и эффективнее, чем FileReader поскольку он считывает целый блок данных из входного потока и сохраняет его в буфере для дальнейших вызовов метода чтения, в то время как FileReader должен получать доступ к файлу для считывания каждого символа. Более того, FileReader может читать файл только посимвольно, в то время как BufferedReader имеет такие полезные методы, как readLine(), который может считать из буфера сразу целую строку. И наконец, FileReader может производить чтение только из файла, а BufferedReader может читать из любого типа потока символьных входных данных (файл, консоль, строка и т.д.):

FileReader

BufferedReader

Медленнее и менее эффективен

Быстрее и эффективнее

Может читать только посимвольно

Может читать символы и строки

Можно читать только из файла

Может читать из любого символьного потока

Вам может быть достаточно и FileReader, если вы читаете из небольших файлов, или когда вызовов операции чтения не очень много. Однако для больших файлов или когда нужно выполнять много операций чтения данных, BufferedReader — это лучший вариант.

5. Заключение

В этом туториале мы с вами рассмотрели различия между FileReader и BufferedReader и когда их следует применять.

Как всегда, полный исходный код туториала доступен на GitHub.


Уже сегодня вечером состоится открытое занятие, на котором познакомимся с Reactor Kafka. На этом уроке посмотрим, как в java-приложении можно работать с Kafka в реактивном стиле. Разберемся, для чего это может быть полезно и когда стоит использовать.

Зарегистрироваться на открытое занятие можно на странице курса "Java Developer Professional".

Теги:
Хабы:
Всего голосов 18: ↑7 и ↓11-3
Комментарии17

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS