【问题标题】:Java: How to get input from System.console()Java:如何从 System.console() 获取输入
【发布时间】:2011-01-10 07:01:16
【问题描述】:

我正在尝试使用控制台类从用户那里获取输入,但是当我调用 System.console() 时返回了一个空对象。在使用 System.console 之前我是否需要进行任何更改?

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

【问题讨论】:

  • 这是安卓版吗? (我从您的用户 ID 猜测)
  • 你是用eclipse来启动你的程序吗?尝试使用 java.exe 在没有 Eclipse 的情况下启动您的程序。
  • 看看 McDowell 的项目“AbstractingTheJavaConsole”:illegalargumentexception.googlecode.com/svn/trunk/code/java/…
  • @RyanFernandes 他的名字与他的问题有什么关系?

标签: java


【解决方案1】:

使用控制台读取输入(只能在 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(),请阅读此solution from McDowell

【讨论】:

  • 为什么我们需要 BufferedReader 来读取输入为什么我们不能直接从 InputStreamReader 读取
  • 得到了答案:使用 BufferedInputStream,该方法委托给一个重载的 read() 方法,该方法读取 8192 个字节并将它们缓冲直到需要它们为止。它仍然只返回单个字节(但保留其他字节)。通过这种方式,BufferedInputStream 减少了对操作系统的本机调用以从文件中读取。谢谢
  • 如果我们想从用户那里读取密码,stackoverflow.com/questions/22545603/… 用星号屏蔽该行。
  • @Learner 另一个原因可能是 BufferedReader 提供了 readLine() 方法,而 InputStreamReader 不存在。
【解决方案2】:
Scanner in = new Scanner(System.in);

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

【讨论】:

  • 但是nextLine() 使用起来非常混乱。在尝试从控制台获取整行时,充其量只会让您头疼。
  • @Yokhen 你能举一个in.nextLine() 会产生问题的例子吗?
  • (1) 默认情况下,Scanner的分隔符是空格,所以当用户输入多个文本时,会导致软件继续执行下几个next(),我们软件中的逻辑会出错。 (2) 如果我使用 nextLine() 来阅读包括空格和 \n\r 在内的整个句子,我需要 trim() 用户输入。 (3) next() 将等待用户输入,但 nextLine() 不会。 (4) 我测试了 useDelimiter("\\r\\n"),但它导致我们软件中其他地方的 next() 逻辑再次出错。结论,使用 Scanner 读取用户输入确实是相当混乱。 BufferedReader 是最好的。
  • 我的扫描仪也有问题,特别是我收到了一个我不太明白的java.util.NoSuchElementException
  • 所有这些都应该在 try-with-resources 中,如果你想读取一行,方法应该是 in.nextLine()。
【解决方案3】:

有几种方法可以从您的控制台/键盘读取输入字符串。以下示例代码展示了如何使用 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 类。通过 Eclipse 运行演示代码时,您无法从 System.console() 获取控制台实例。因为 eclipse 将您的应用程序作为后台进程运行,而不是作为具有系统控制台的顶级进程。

【讨论】:

    【解决方案4】:

    这取决于您的环境。例如,如果您通过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)。

    【讨论】:

      【解决方案5】:

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

      import java.util.Scanner;
      String data;
      
      Scanner scanInput = new Scanner(System.in);
      data= scanInput.nextLine();
      
      scanInput.close();            
      System.out.println(data);
      

      【讨论】:

      • 在这种情况下您可能不想调用close() 扫描仪,因为它会关闭 System.in 并阻止您的应用程序稍后读取它。 (稍后阅读会抛出错误“找不到行”)
      • 是的,我同意,如果打算稍后在程序中使用 System.in,则不应使用 close()。
      【解决方案6】:

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

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

      【讨论】:

        【解决方案7】:

        以下内容采用athspk's answer 并使其成为一个不断循环的内容,直到用户键入“exit”。我还写了一个followup answer,我在其中获取了这段代码并使其可测试。

        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.
        

        【讨论】:

          【解决方案8】:

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

          它引入了类似于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 + ".");
          

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

          【讨论】:

            【解决方案9】:
            猜你喜欢
            • 2015-06-08
            • 1970-01-01
            • 2015-08-18
            • 1970-01-01
            • 1970-01-01
            • 2021-04-16
            • 1970-01-01
            • 2013-04-29
            • 2011-10-19
            相关资源
            最近更新 更多