Intentando leer desde la consola en Java

Acabo de empezar a aprender Java con IntelliJ IDE. Sé un poco C # así que la lógica tiene algún sentido, sin embargo hay una cosa hasta ahora que no pude superar.

¿Cómo leo desde la consola? En C #, puede leer fácilmente lo que el ser humano tipeó en él, utilizando Console.ReadLine() . En Java, System.console().readLine(); no funciona para mí y arroja una NullPointerException .

¿Que me estoy perdiendo aqui?

Problema

La mayoría de los IDE utilizan javaw.exe lugar de java.exe para ejecutar código Java (ver imagen a continuación).

La diferencia entre estos dos progtwigs es que javaw ejecuta código Java sin asociación con el terminal / consola actual (que es útil para aplicaciones GUI), y dado que no hay una ventana de consola asociada, System.console() devuelve null . Debido a que System.console().readLine() termina como null.readLine() que lanza NullPointerException ya que null no tiene el método readLine() (ni ningún método / campo).

Pero el hecho de que no haya una consola asociada no significa que no podamos comunicarnos con el proceso de javaw . Este proceso aún admite flujos de entrada / salida / error estándar, por lo que el proceso de IDE (y también a través de él) puede usarlos a través de System.in , System.out y System.err .

De esta forma, los IDEs pueden tener alguna pestaña / ventana y dejar que simule la consola.

Por ejemplo, cuando ejecutamos código como en 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()); } } 

veremos como resultado

enter image description here

que muestra que a pesar de que javaw.exe no tiene una consola asociada ( null al final), IDE pudo manejar los datos de la salida estándar del proceso javaw System.out.println("hello world"); y mostrar hello world .

Solución general

Para permitir que el usuario pase información para procesar use la stream de entrada estándar ( System.in ). Pero dado que in es simple InputStream y Stream s están destinados a manejar datos binarios , no tiene métodos que le permitan leer datos de manera fácil y adecuada como texto (especialmente si la encoding puede estar involucrada). Es por eso que los Readers y Writers se agregaron a Java.

Para facilitar la vida y dejar que la aplicación lea los datos del usuario como texto, puede envolver esta secuencia en uno de los Reader , como BufferedReader que le permitirá leer toda la línea con el método readLine() . Desafortunadamente esta clase no acepta Streams sino Reader ‘s, por lo que necesitamos algún tipo de adaptador que simule Reader y sea capaz de traducir bytes a texto. Pero es por eso que existe InputStreamReader .

Entonces, el código que permitiría que la aplicación lea datos del flujo de entrada podría verse como

 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); 

Solución preferida / más simple – Escáner

Para evitar esta magia que implica la conversión de Stream a Reader, puede usar la clase Scanner , que está destinada a leer datos como texto de Streams y Lectores.

Esto significa que puedes simplemente usar

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

para leer los datos del usuario (que se enviarán por consola simulada por IDE utilizando flujo de entrada estándar).

java.util.Scanner API es lo que estás buscando.

Si realmente necesita un objeto Console, puede comstackr su clase desde la línea de comandos. En primer lugar, en mi primera statement del archivo java es el package com.inputOutput;

Vaya a la carpeta del proyecto ” src ” y javac com/inputOutput/Password.java como: ” javac com/inputOutput/Password.java ” ‘ com ‘ y ‘ inputOutput ‘ son carpetas (paquete). Ejecute su archivo de clase en la carpeta src
java com.inputOutput.Password “. Me había funcionado el trabajo.