Java: Como obter entrada de System.console ()

163

Estou tentando usar a classe Console para obter entrada do usuário, mas um objeto nulo é retornado quando ligo System.console(). Preciso alterar alguma coisa antes de usar o System.console?

Console co=System.console();
System.out.println(co);
try{
    String s=co.readLine();
}
satheesh.droid
fonte
1
isso é para android? (i estou supondo que a partir de sua identificação de usuário)
Ryan Fernandes
Você está usando o eclipse para iniciar seu programa? Tente iniciar seu programa sem eclipse usando java.exe.
keuleJ
5
Ter um olhar para o projeto de McDowell "AbstractingTheJavaConsole": illegalargumentexception.googlecode.com/svn/trunk/code/java/...
athspk
7
@RyanFernandes Como o nome dele é relevante para sua pergunta?
B1nary.atr0phy

Respostas:

239

Usando o Console para ler a entrada (utilizável apenas fora de um IDE):

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

Outra maneira (funciona em qualquer lugar):

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 () retorna nulo em um IDE.
Portanto, se você realmente precisar usar System.console(), leia esta solução no McDowell .

athspk
fonte
Por que precisamos de BufferedReader para ler a entrada porque nos nao podemos ler diretamente InputStreamReader
Learner
2
Obteve a resposta: Com um BufferedInputStream, o método delega para um método read () sobrecarregado que lê a quantidade de 8192 bytes e os armazena em buffer até que sejam necessários. Ele ainda retorna apenas o byte único (mas mantém os outros em reserva). Dessa forma, o BufferedInputStream faz menos chamadas nativas para o sistema operacional para ler o arquivo. Obrigado
aprendiz
Caso desejemos ler a senha do usuário, stackoverflow.com/questions/22545603/… mascara a linha com asterisco.
oraclesoon
@ Aluno outro motivo pode ser que o BufferedReader forneça o método readLine()que não existe InputStreamReader.
Marcono1234 24/07/19
116
Scanner in = new Scanner(System.in);

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

fonte
4
No entanto, nextLine()é muito confuso trabalhar com isso. Na melhor das hipóteses, você terá dor de cabeça ao tentar obter linhas inteiras do console.
Yokhen
9
@Yokhen você poderia, por favor, dar um exemplo onde in.nextLine()criaria problemas?
ajay
2
(1) Por padrão, o delimitador do Scanner é o espaço; portanto, quando o usuário digita vários textos, o software prossegue para os próximos () e a lógica do software está errada. (2) Se eu usar nextLine () para ler a frase completa, incluindo espaço e \ n \ r, preciso aparar () a entrada do usuário. (3) next () aguardará a entrada do usuário, mas nextLine () não. (4) Testei o useDelimiter ("\\ r \\ n"), mas faz com que a próxima () lógica do nosso software em outro lugar esteja errada novamente. Conclusão, é realmente bastante confuso usar o Scanner para ler a entrada do usuário. BufferedReader é o melhor.
oraclesoon
Também tenho problemas com o scanner, principalmente quando recebo um java.util.NoSuchElementExceptionque não entendo direito.
Romain Vincent
Tudo isso deve estar dentro de uma tentativa com recursos e o método deve estar em.nextLine () se você quiser ler uma linha.
Calabacin
35

Existem algumas maneiras de ler a string de entrada do seu console / teclado. O código de amostra a seguir mostra como ler uma seqüência de caracteres do console / teclado usando 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);

}
}

A última parte do código usou a java.io.Consoleclasse não é possível obter a instância do console System.console()ao executar o código de demonstração através do Eclipse. Porque o eclipse executa seu aplicativo como um processo em segundo plano e não como um processo de nível superior com um console do sistema.

pankaj
fonte
18

Vai depender do seu ambiente. Se você estiver executando um UI balanço via javawpor exemplo, então há não é um console para exibir. Se você estiver executando em um IDE, isso dependerá muito do tratamento do IDE específico do IO do console.

Na linha de comando, deve ficar bem. Amostra:

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

Execute isso apenas com java:

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

Outra opção é usar System.in, que você pode agrupar em BufferedReaderlinhas para ler, ou usar Scanner(agrupar novamente System.in).

Jon Skeet
fonte
7

Encontrei uma boa resposta aqui sobre a leitura do console, aqui outra maneira de usar o 'Scanner' para ler do console:

import java.util.Scanner;
String data;

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

scanInput.close();            
System.out.println(data);
akhouri
fonte
1
Talvez você não queira ligar para close()o scanner nesse caso, porque ele fechará o System.in e impedirá que seu aplicativo o leia mais tarde. (A leitura posterior gera o erro "nenhuma linha encontrada")
Trevor
Sim, eu concordo com isso, close () não deve ser usado se a intenção for usar System.in posteriormente no programa.
akhouri
5

Tente isso. espero que isso ajude.

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

fonte
3

A seguir, a resposta do athspk é transformada em uma que faz um loop contínuo até o usuário digitar "exit". Também escrevi uma resposta de acompanhamento em que peguei esse código e o testei.

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...");
      }
   }
}

Exemplo de saída:

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.
aliteralmind
fonte
3

Eu escrevi a biblioteca Text-IO , que pode lidar com o problema de System.console () ser nulo ao executar um aplicativo a partir de um IDE.

Introduz uma camada de abstração semelhante à proposta por McDowell . Se System.console () retornar nulo, a biblioteca alterna para um console baseado em Swing.

Além disso, o Text-IO possui uma série de recursos úteis:

  • suporta leitura de valores com vários tipos de dados.
  • permite mascarar a entrada ao ler dados confidenciais.
  • permite selecionar um valor de uma lista.
  • permite especificar restrições nos valores de entrada (padrões de formato, intervalos de valores, restrições de comprimento etc.).

Exemplo 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 + ".");

Em esta imagem você pode ver o código acima executado em um console baseado em Swing.

siordache
fonte