Попытка чтения с консоли в Java

Я только начал изучать Java с IntelliJ IDE. Я немного знаю С#, поэтому логика имеет какой-то смысл, однако до сих пор я не мог ее преодолеть.

Как читать с консоли? В С# вы можете легко прочитать, что набирал человек, используя Console.ReadLine(). В Java System.console().readLine(); не работает для меня и выбрасывает NullPointerException.

Что мне здесь не хватает?

Ответ 1

Проблема

Большинство IDE используют javaw.exe вместо java.exe для запуска Java-кода (см. рисунок ниже).

Разница между этими двумя программами заключается в том, что javaw запускает код Java без связи с текущим терминалом/консолью (что полезно для приложений GUI), и поскольку нет связанного окна консоли System.console() возвращает null. Из-за этого System.console().readLine() заканчивается как null.readLine(), который выдает NullPointerException, так как null не имеет метода readLine() (и никакого метода/поля).

Но только потому, что нет связанной консоли, это не значит, что мы не можем общаться с процессом javaw. Этот процесс по-прежнему поддерживает стандартные потоки ввода/вывода/ошибок, поэтому процесс IDE (и через него также мы) может использовать их через System.in, System.out и System.err.

Таким образом, IDE могут иметь некоторую вкладку/окно и позволить имитировать консоль.

Например, когда мы запускаем код, как в Eclipse:

package com.stackoverflow;

public class Demo {

    public static void main(String[] args) throws Exception {
        System.out.println("hello world");
        System.out.println(System.console());
    }

}

мы увидим как результат

enter image description here

который показывает, что несмотря на то, что javaw.exe не имеет связанной консоли (null в конце), IDE смогла обработать данные из стандартного вывода процесса javaw System.out.println("hello world"); и показать hello world.

Общее решение

Чтобы пользователь мог передавать информацию для обработки, используйте стандартный поток ввода (System.in). Но так как in прост InputStream и Stream предназначены для обработки двоичных данных, у него нет методов, которые позволяли бы ему легко и правильно читать данные в виде текста (особенно если кодирование может быть задействовано). Вот почему Readers и Writers ware добавлены в Java.

Итак, чтобы облегчить жизнь и позволить программе читать данные от пользователя в виде текста, вы можете обернуть этот поток в один из Reader, как BufferedReader, который позволит вам прочитать целую строку с помощью метода readLine(). К сожалению, этот класс не принимает Streams, но Reader s, поэтому нам нужен какой-то адаптер, который будет имитировать Reader и сможет переводить байты в текст. Но вот почему InputStreamReader существует.

Таким образом, код, который позволит приложениям считывать данные из входного потока, может выглядеть как

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Hello. Please write your name: ");
String name = br.readLine();
System.out.println("Your name is: "+name);

Предпочтительное/простейшее решение - Сканер

Чтобы избежать этой магии, связанной с преобразованием Stream в Reader, вы можете использовать класс Scanner, который предназначен для чтения данных в виде текста из Streams and Readers.

Это означает, что вы можете просто использовать

Scanner scanner = new Scanner(System.in);
//...
String name = scanner.nextLine();

для чтения данных от пользователя (которые будут отправляться с помощью консоли, моделируемой IDE, с использованием стандартного потока ввода).

Ответ 2

java.util.Scanner API - это то, что вы ищете.

Ответ 3

Если вам действительно нужен объект Console, вы можете скомпилировать свой класс из командной строки. Во-первых, в моем Java файле первый оператор - это package com.inputOutput;

Перейдите в папку " src " вашего проекта и скомпилируйте ее так: " javac com/inputOutput/Password.java ", " com " и " inputOutput - это папка (пакет). Запустите ваш файл класса в папке src
java com.inputOutput.Password ". Это сработало для меня.

Ответ 4

Вы могли бы использовать Jframe.

JFrame frame = new JFrame("titile");

// prompt the user to enter their code
String code = JOptionPane.showInputDialog(frame, "promt here");