Java:如何从System.console()获取输入


163

我正在尝试使用Console类从用户获取输入,但是在调用时返回空对象System.console()。使用System.console之前我是否需要更改任何内容?

Console co=System.console();
System.out.println(co);
try{
    String s=co.readLine();
}

1
这是android吗?(我是根据您的用户ID猜测的)
Ryan Fernandes

您是否正在使用eclipse启动程序?尝试使用java.exe在没有日食的情况下启动程序。
keuleJ 2011年

5
看看麦克道尔的项目“AbstractingTheJavaConsole”: illegalargumentexception.googlecode.com/svn/trunk/code/java/...
athspk

7
@RyanFernandes他的名字与他的问题有什么关系?
b1nary.atr0phy

Answers:


239

使用控制台读取输入(仅在IDE外部可用):

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

另一种方法(可在任何地方使用):

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()在IDE中返回null。
因此,如果您真的需要使用System.console(),请阅读McDowell的解决方案


为什么我们需要BufferedReader来读取输入,为什么我们不能直接从InputStreamReader中读取
学习者

2
得到答案:有了BufferedInputStream,该方法将委托给一个重载的read()方法,该方法读取8192个字节的字节并对其进行缓冲,直到需要它们为止。它仍然只返回单个字节(但保留其他字节)。这样,BufferedInputStream可以减少对OS进行本机调用以从文件读取的次数。谢谢
学习者2016年

万一我们想从用户那里读取密码,stackoverflow.com/questions/ 22545603/…用星号遮住行。
oraclesoon

@Learner的另一个原因可能是BufferedReader提供了readLine()不存在的方法InputStreamReader
Marcono1234 '19

116
Scanner in = new Scanner(System.in);

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

4
但是,使用nextLine()它非常麻烦。尝试从控制台获取整行内容时,充其量只会让您头疼。
Yokhen 2013年

9
@Yokhen您能举个例子说明哪里in.nextLine()会造成问题吗?
2015年

2
(1)默认情况下,Scanner的定界符为空格,因此当用户输入多个文本时,它将导致软件继续进行下几个next()操作,并且我们软件中的逻辑错误。(2)如果我使用nextLine()读取包括空格和\ n \ r在内的整个句子,则需要trim()用户输入。(3)next()将等待用户输入,但nextLine()不会。(4)我测试了useDelimiter(“ \\ r \\ n”),但它导致我们其他地方的软件中的next()逻辑再次出错。结论,使用Scanner读取用户输入确实非常混乱。BufferedReader是最好的。
oraclesoon

我也遇到扫描仪问题,尤其是我得到了一个java.util.NoSuchElementException我不太了解的问题。
罗曼·文森特

所有这些都应该放在try-with-resources内部,如果要读取一行,则方法应该在in.nextLine()中。
Calabacin

35

从控制台/键盘读取输入字符串的方法很少。以下示例代码显示了如何使用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);

}
}

代码的最后一部分使用了java.io.Console类。System.console()通过Eclipse运行演示代码时,您将无法获得Console实例。因为eclipse将您的应用程序作为后台进程而不是系统控制台的顶级进程运行。


18

这将取决于您的环境。javaw例如,如果您通过运行Swing UI ,则没有可显示的控制台。如果您在IDE中运行,则将在很大程度上取决于特定IDE对控制台IO的处理。

从命令行,它应该没问题。样品:

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

仅使用java以下命令运行此命令:

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

另一种选择是使用System.in,您可能希望将其换BufferedReader行以读取行,或者使用Scanner(再次换行System.in)。


7

在这里找到了一些有关从控制台读取的好答案,这是另一种使用“扫描仪”从控制台读取的方法:

import java.util.Scanner;
String data;

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

scanInput.close();            
System.out.println(data);

1
close()在这种情况下,您可能不希望调用扫描仪,因为它将关闭System.in并阻止您的应用程序稍后再读取它。(稍后阅读会引发错误“找不到行”)
Trevor

是的,我同意,如果打算在程序的后面使用System.in,则不应使用close()。
akhouri 2014年

5

试试这个。希望这会有所帮助。

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

3

以下内容是athspk的答案,并使其成为一个连续循环,直到用户键入“退出”为止。我还编写了一个后续答案,在此代码中使用了该代码并使之可测试。

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

输出示例:

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.

3

我编写了Text-IO库,该库可以处理从IDE中运行应用程序时System.console()为null的问题。

它引入了类似于McDowell提出的抽象层。如果System.console()返回null,则库将切换到基于Swing的控制台。

另外,Text-IO具有一系列有用的功能:

  • 支持读取具有各种数据类型的值。
  • 允许在读取敏感数据时屏蔽输入。
  • 允许从列表中选择一个值。
  • 允许指定对输入值的约束(格式模式,值范围,长度约束等)。

用法示例:

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

此图中,您可以看到以上代码在基于Swing的控制台中运行。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.