Эта статья адресована в первую очередь начинающим Java программистам.
Обычно вывод данных на консоль трудностей не представляет с System.out.print или System.out.println, как правило, справляются все. Но когда же дело доходит до ввода данных возникают трудности.
Виной тому неудобная и сложная для восприятия реализация консольного ввода в Java. Но тем не менее его можно освоить если изучить его работу.
Последняя строится на основе двух классов: InputStream (System.in) и Scanner.
Ввод с использованием InputStream (System.in)
Java получает данные из консоли при помощи системного потока ввода (Isystem.in) поэтому данный способ ввода может показаться очевидным. Но, к сожалению, он имеет один серьёзный недостаток.
Дело в том, что системный поток ввода получает только числовые коды символов, которые введены в окно консоли и больше ничего. Причём за один раз из него можно прочитать код только одного символа. Поэтому для того чтобы прочитать слово или строку необходимо использовать цикл.
Ниже приведён пример считывания введённой в консоли строки подобным образом.
1 2 3 4 5 6 7 8 9 10 11 |
int inChar; String s = ""; try { inChar = System.in.read(); while (System.in.available() > 0) { s += (char) inChar; inChar = System.in.read(); } } catch (IOException e) { System.out.println("Ошибка"); } |
Пока в потоке ввода есть данные (метод available возвращает значение больше нуля), мы раз разом считываем код символа, затем преобразуем его в собственно сам символ и добавляем этот символ в конец строки.
На этом неудобства данного подхода не заканчиваются потому, что мы всегда получаем данные в строковом формате. Если же нам требуется ввести, допустим, целое число? Тогда нам придётся дополнить вышеприведённый пример приведением типов с соответствующей проверкой.
Поэтому для получения данных от пользователя в консольных приложениях системный поток ввода на прямую сейчас почти не используется. Вместо него предпочтительнее работать с классом Scanner.
Ввод с использованием Scanner
Класс Scanner позволяет избежать всех трудностей, связанных с использованием системного потока ввода и максимально упростить ввод данных от пользователей в консольных приложениях.
Экземпляр класса Scanner создаётся при помощи конструктора, который принимает в качестве единственного параметра поток ввода. После этого можно сразу считывать готовые данные при помощи семейства методов с префиксом next.
Вот пример, который демонстрирует считывание введённой в консоли строки. В конструктор передаётся системный поток ввода.
1 2 3 |
Scanner in = new Scanner(System.in); System.out.print("Введите строку: "); String str = in.nextLine(); |
Если сравнить этот пример с приведённым ранее прямым считыванием строки из системного потока ввода, то преимущество класса Scanner очевидно. Ведь нам уже не требуется вручную считывать коды символов и формировать строку в цикле. Класс Scanner самостоятельно выполняет все рутинные низкоуровневые функции, предоставляя данные, которые уже готовы к использованию в программе.
Как уже говорилось выше, класс Scanner имеет целый ряд методов для считывания данных, но все они отличаются друг от друга только типами возвращаемых значений и соответствующими им названиями.
Так, помимо метода nextLine, существуют методы nextBoolean, nextByte, nextInt, nextDouble и другие.
Кроме того, имеется ряд методов с префиксом hasNext, которые позволяют определить тип считываемых данных. Например, hasNextLine, hasNextInt, hasNextBollean и т. д. Если в потоке ввода находятся данные соответствующего типа, эти методы возвращают true.
Пример:
1 2 3 4 5 |
Scanner in = new Scanner(System.in); System.out.print("Введите строку: "); if (in.hasNextLine()){ String str = in.nextLine(); } |
Это позволяет обеспечить безопасность получения данных в отношении несоответствия типов.
Таким образом, получить данные консольного ввода в Java не так сложно как кажется, если использовать не системный поток ввода, а класс Scanner.
Добавить комментарий