teclado - leer desde consola java
Intentando leer desde la consola en Java (3)
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 programas 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.;
public class Demo {
public static void main(String[] args) throws Exception {
System.out.println("hello world");
System.out.println(System.console());
}
}
veremos como resultado
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 corriente 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 codificación 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).
Si realmente necesita un objeto Console, puede compilar su clase desde la línea de comandos. En primer lugar, en mi primera declaración 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.
java.util.Scanner
API es lo que estás buscando.