Java: cómo obtener información de System.console ()

163

Estoy tratando de usar la clase de consola para obtener información del usuario, pero cuando llamo, se devuelve un objeto nulo System.console(). ¿Tengo que cambiar algo antes de usar System.console?

Console co=System.console();
System.out.println(co);
try{
    String s=co.readLine();
}
satheesh.droid
fuente
1
¿Es esto para Android? (Supongo que por su identificación de usuario)
Ryan Fernandes
¿Estás usando eclipse para iniciar tu programa? Intente iniciar su programa sin eclipse con java.exe.
keuleJ
55
Echa un vistazo al proyecto de McDowell "AbstractingTheJavaConsole": illegalargumentexception.googlecode.com/svn/trunk/code/java/…
athspk
77
@RyanFernandes ¿Cómo es su nombre relevante para su pregunta?
b1nary.atr0phy

Respuestas:

239

Uso de la consola para leer la entrada (solo se puede usar fuera de un IDE):

System.out.print("Enter something:");
String input = System.console().readLine();

Otra forma (funciona en todas partes):

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {
    public static void main(String[] args) throws IOException { 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print("Enter String");
        String s = br.readLine();
        System.out.print("Enter Integer:");
        try {
            int i = Integer.parseInt(br.readLine());
        } catch(NumberFormatException nfe) {
            System.err.println("Invalid Format!");
        }
    }
}

System.console () devuelve nulo en un IDE.
Entonces, si realmente necesita usar System.console(), lea esta solución de McDowell .

athspk
fuente
por qué necesitamos BufferedReader para leer la entrada por qué no podemos leer directamente desde InputStreamReader
Estudiante
2
Obtuve la respuesta: con un BufferedInputStream, el método delega a un método read () sobrecargado que lee una cantidad de 8192 bytes y los almacena hasta que se necesiten. Todavía devuelve solo el byte único (pero mantiene a los demás en reserva). De esta manera, BufferedInputStream realiza menos llamadas nativas al sistema operativo para leer desde el archivo. Gracias
Estudiante
En caso de que queramos leer la contraseña del usuario, stackoverflow.com/questions/22545603/… enmascara la línea con un asterisco.
orraclesoon
@Learner otra razón podría ser que BufferedReader proporciona el método para el readLine()que no existe InputStreamReader.
Marcono1234
116
Scanner in = new Scanner(System.in);

int i = in.nextInt();
String s = in.next();

fuente
44
Sin embargo, nextLine()es muy complicado trabajar con él. En el mejor de los casos, le dará dolor de cabeza cuando intente obtener líneas completas de la consola.
Yokhen
9
@Yokhen, ¿podría dar un ejemplo de dónde in.nextLine()crearía problemas?
ajay
2
(1) De forma predeterminada, el delimitador de Scanner es espacio, por lo que cuando el usuario ingresa varios textos, el software continuará con los siguientes próximos () y la lógica en nuestro software será incorrecta. (2) Si uso nextLine () para leer la oración completa que incluye el espacio y \ n \ r, necesito recortar () la entrada del usuario. (3) next () esperará la entrada del usuario pero nextLine () no lo hará. (4) Probé useDelimiter ("\\ r \\ n"), pero hace que la lógica next () en nuestro software en algún otro lugar vuelva a estar equivocada. Conclusión, de hecho es bastante complicado usar Scanner para leer la entrada del usuario. BufferedReader es el mejor.
orraclesoon
También tengo problemas con el escáner, en particular me sale uno java.util.NoSuchElementExceptionque no entiendo bien.
Romain Vincent
Todo esto debe estar dentro de una prueba con recursos y el método debe estar en.nextLine () si desea leer una línea.
Calabacin
35

Hay pocas formas de leer la cadena de entrada desde su consola / teclado. El siguiente código de muestra muestra cómo leer una cadena desde la consola / teclado utilizando Java.

public class ConsoleReadingDemo {

public static void main(String[] args) {

    // ====
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    System.out.print("Please enter user name : ");
    String username = null;
    try {
        username = reader.readLine();
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println("You entered : " + username);

    // ===== In Java 5, Java.util,Scanner is used for this purpose.
    Scanner in = new Scanner(System.in);
    System.out.print("Please enter user name : ");
    username = in.nextLine();      
    System.out.println("You entered : " + username);


    // ====== Java 6
    Console console = System.console();
    username = console.readLine("Please enter user name : ");   
    System.out.println("You entered : " + username);

}
}

La última parte del código utilizado java.io.Consoleclase. no puede obtener la instancia de la Consola System.console()cuando ejecuta el código de demostración a través de Eclipse. Porque eclipse ejecuta su aplicación como un proceso en segundo plano y no como un proceso de nivel superior con una consola del sistema.

pankaj
fuente
18

Dependerá de su entorno. Si está ejecutando una interfaz de usuario Swing a través de, javawpor ejemplo, entonces no hay una consola para mostrar. Si está ejecutando dentro de un IDE, dependerá en gran medida del manejo específico de IDE de la consola IO.

Sin embargo, desde la línea de comando, debería estar bien. Muestra:

import java.io.Console;

public class Test {

    public static void main(String[] args) throws Exception {
        Console console = System.console();
        if (console == null) {
            System.out.println("Unable to fetch console");
            return;
        }
        String line = console.readLine();
        console.printf("I saw this line: %s", line);
    }
}

Ejecute esto solo con java:

> javac Test.java
> java Test
Foo  <---- entered by the user
I saw this line: Foo    <---- program output

Otra opción es usar System.in, que quizás desee ajustar en una línea BufferedReaderde lectura, o usar Scanner(nuevamente ajustar System.in).

Jon Skeet
fuente
7

Encontré una buena respuesta aquí con respecto a la lectura desde la consola, aquí otra forma de usar 'Scanner' para leer desde la consola:

import java.util.Scanner;
String data;

Scanner scanInput = new Scanner(System.in);
data= scanInput.nextLine();

scanInput.close();            
System.out.println(data);
akhouri
fuente
1
Es posible que no desee llamar close()al escáner en este caso, porque cerrará System.in y evitará que su aplicación lea más tarde. (Leer más tarde arroja el error "no se encontró línea")
Trevor
Sí, estoy de acuerdo con eso, close () no debe usarse si la intención es usar System.in más adelante en el programa.
akhouri
5

Prueba esto. Espero que esto ayude.

    String cls0;
    String cls1;

    Scanner in = new Scanner(System.in);  
    System.out.println("Enter a string");  
    cls0 = in.nextLine();  

    System.out.println("Enter a string");  
    cls1 = in.nextLine(); 

fuente
3

Lo siguiente toma la respuesta de athspk y la convierte en una que se repite continuamente hasta que el usuario escribe "salir". También escribí una respuesta de seguimiento donde tomé este código y lo hice comprobable.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class LoopingConsoleInputExample {

   public static final String EXIT_COMMAND = "exit";

   public static void main(final String[] args) throws IOException {
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      System.out.println("Enter some text, or '" + EXIT_COMMAND + "' to quit");

      while (true) {

         System.out.print("> ");
         String input = br.readLine();
         System.out.println(input);

         if (input.length() == EXIT_COMMAND.length() && input.toLowerCase().equals(EXIT_COMMAND)) {
            System.out.println("Exiting.");
            return;
         }

         System.out.println("...response goes here...");
      }
   }
}

Salida de ejemplo:

Enter some text, or 'exit' to quit
> one
one
...response goes here...
> two
two
...response goes here...
> three
three
...response goes here...
> exit
exit
Exiting.
mente mental
fuente
3

Escribí la biblioteca Text-IO , que puede solucionar el problema de que System.console () sea nulo cuando se ejecuta una aplicación desde un IDE.

Introduce una capa de abstracción similar a la propuesta por McDowell . Si System.console () devuelve nulo, la biblioteca cambia a una consola basada en Swing.

Además, Text-IO tiene una serie de características útiles:

  • admite valores de lectura con varios tipos de datos.
  • permite enmascarar la entrada al leer datos confidenciales.
  • permite seleccionar un valor de una lista.
  • permite especificar restricciones en los valores de entrada (patrones de formato, rangos de valores, restricciones de longitud, etc.).

Ejemplo de uso:

TextIO textIO = TextIoFactory.getTextIO();

String user = textIO.newStringInputReader()
        .withDefaultValue("admin")
        .read("Username");

String password = textIO.newStringInputReader()
        .withMinLength(6)
        .withInputMasking(true)
        .read("Password");

int age = textIO.newIntInputReader()
        .withMinVal(13)
        .read("Age");

Month month = textIO.newEnumInputReader(Month.class)
        .read("What month were you born in?");

textIO.getTextTerminal().println("User " + user + " is " + age + " years old, " +
        "was born in " + month + " and has the password " + password + ".");

En esta imagen , puede ver el código anterior ejecutándose en una consola basada en Swing.

siordache
fuente