Рубрики
Без рубрики

BufferedReader vs Console vs Scanner в Java

Быстрое и практичное сравнение BufferedReader, консоли и сканера в Java.

Автор оригинала: baeldung.

1. Обзор

В этой статье мы рассмотрим различия между классами BufferedReader , Console и Scanner в Java .

Чтобы глубоко погрузиться в каждую тему, мы предлагаем ознакомиться с нашими отдельными статьями по Java Scanner , консольному вводу-выводу в Java и BufferedReader .

2. Ввод Данных Пользователем

Учитывая базовый поток, передаваемый конструкторам, оба класса BufferedReader и Scanner способны обрабатывать более широкий диапазон пользовательского ввода , такой как строка, файл, системная консоль (которая обычно подключается к клавиатуре) и сокет.

С другой стороны, класс Console предназначен только для доступа к символьной системной консоли, если таковая имеется, связанной с текущей виртуальной машиной Java.

Давайте посмотрим на конструкторы BufferedReader , которые принимают различные входные данные:

BufferedReader br = new BufferedReader(
  new StringReader("Bufferedreader vs Console vs Scanner in Java"));
BufferedReader br = new BufferedReader(
  new FileReader("file.txt"));
BufferedReader br = new BufferedReader(
  new InputStreamReader(System.in))

Socket socket = new Socket(hostName, portNumber);
BufferedReader br =  new BufferedReader(
  new InputStreamReader(socket.getInputStream()));

Класс Scanner также может принимать различные входные данные в своих конструкторах:

Scanner sc = new Scanner("Bufferedreader vs Console vs Scanner in Java")
Scanner sc = new Scanner(new File("file.txt"));
Scanner sc = new Scanner(System.in);

Socket socket = new Socket(hostName, portNumber);
Scanner sc =  new Scanner(socket.getInputStream());

Класс Console доступен только через вызов метода:

Console console = System.console();

Пожалуйста, имейте в виду, что когда мы используем класс Console , связанная с JVM системная консоль недоступна, если мы запускаем код в IDE, такой как Eclipse или IntelliJ IDEA.

3. Пользовательский вывод

В отличие от классов BufferedReader и Scanner , которые ничего не записывают в выходной поток, класс Console предлагает некоторые удобные методы такие как readPassword (String fmt, Object… args), readLine (String fmt, Object… args), и printf (String format,Object… args) , для записи приглашения в выходной поток системной консоли :

String firstName = console.readLine("Enter your first name please: ");
console.printf("Welcome " + firstName );

Поэтому, когда мы пишем программу для взаимодействия с системной консолью, класс Console упростит код, удалив ненужный System.out.println .

4. Анализ Входных данных

Класс Scanner может анализировать примитивные типы и строки с помощью регулярных выражений .

Он разбивает свои входные данные на токены, используя пользовательский шаблон разделителя, который по умолчанию соответствует пробелам:

String input = "Bufferedreader vs Console vs Scanner";
Scanner sc = new Scanner(input).useDelimiter("\\s*vs\\s*");
System.out.println(sc.next());
System.out.println(sc.next());
System.out.println(sc.next());
sc.close();

Классы Bufferedreader и Console просто считывают входной поток таким, какой он есть.

5. Чтение Защищенных Данных

Класс Console имеет методы readPassword() и readPassword (String fmt , Object… args) для чтения защищенных данных с отключенным эхом, чтобы пользователи не видели, что они набирают:

String password = String.valueOf(console.readPassword("Password :"));

BufferedReader и Сканер не имеют возможности сделать это.

6. Резьбобезопасность

Методы чтения в BufferedReader и методы чтения и записи в Console все синхронизированы , в то время как методы в классе Scanner – нет. Если мы читаем пользовательский ввод в многопоточной программе, то лучшим вариантом будет либо BufferedReader , либо Console .

7. Размер буфера

Размер буфера составляет 8 КБ в BufferedReader по сравнению с 1 КБ в Scanner class .

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

8. Разное

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

8.1. Закрытие входного потока

Как только мы создадим экземпляр BufferedReader или Scanner , нам нужно не забыть закрыть его, чтобы избежать утечки памяти . Но этого не происходит с классом Console — нам не нужно закрывать системную консоль после использования.

8.2. Обработка исключений

В то время как Scanner и Console идут с непроверенным подходом исключений, методы в BufferedReader бросают проверенные исключения, что заставляет нас писать шаблонный синтаксис try-catch для обработки исключений.

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

Теперь, когда мы определили различия между этими классами, давайте придумаем некоторые эмпирические правила относительно того, какой из них лучше всего подходит для решения различных ситуаций.:

  • Используйте BufferedReader , если нам нужно прочитать длинные строки из файла, так как он имеет лучшую производительность, чем Scanner
  • Рассмотрим Console если мы читаем защищенные данные с системной консоли и хотим скрыть то, что набирается
  • Используйте Scanner , если нам нужно разобрать входной поток с помощью пользовательского регулярного выражения
  • Scanner будет предпочтительнее, когда мы взаимодействуем с системной консолью, так как она предлагает мелкозернистые методы чтения и анализа входного потока. Кроме того, недостаток производительности не является большой проблемой, так как в большинстве случаев методы nextXXX блокируются и ждут ручного ввода
  • В потокобезопасном контексте рассмотрим BufferedReader , если только нам не нужно использовать функции, специфичные для класса Console