试图用Java从控制台读取 [英] Trying to read from the console in Java
问题描述
我刚开始使用IntelliJ IDE学习Java。我知道有点C#所以逻辑是有道理的,但到目前为止有一件事我无法克服它。
我如何从控制台读取?在C#中,您可以使用 Console.ReadLine()
轻松阅读人类键入的内容。在Java中, System.console()。readLine();
对我不起作用并抛出 NullPointerException
。
我在这里缺少什么?
问题
大多数IDE使用 javaw.exe
而不是 java.exe
来运行Java代码(见下图)。
这两个程序的区别在于 javaw
运行Java代码而不与当前终端/控制台相关联(这对GUI应用程序很有用),并且因为没有关联的控制台窗口 System.console()
返回 null
。因为 System.console()。readLine()
最终为 null.readLine()
,它会抛出 NullPointerException
因为 null
没有 readLine()
方法(也不是任何方法/字段)。
但是因为没有关联的控制台,这并不意味着我们无法与 javaw <进行通信/ code>进程。此过程仍支持标准输入/输出/错误流,因此IDE处理(并通过它我们)可以通过
System.in
,系统使用它们.out
和 System.err
。
这样IDE可以有一些标签/窗口,让它模拟控制台。
<例如,当我们在Eclipse中运行代码时:
package com.stackoverflow;
公共类演示{
public static void main(String [] args)抛出异常{
System.out.println(hello world);
System.out.println(System.console());
}
}
我们将看到结果
显示尽管 javaw.exe
最后还没有关联的控制台( null
)IDE能够处理来自 javaw
进程的标准输出的数据 System.out.println(hello world);
并显示 hello world
。
一般解决方案
让用户传递信息以处理使用标准输入流( System.in
)。但由于中的是简单的
InputStream
和流
s是指为了处理二进制数据,它没有方法可以让它轻松,正确地将数据作为文本读取(特别是如果可以涉及编码)。这就是为什么 Readers
和 Writers
ware添加到Java的原因。
因此,为了让生活更轻松,让应用程序以文本形式从用户读取数据,您可以将此流包装在 Reader $ c $之一中c>类似
BufferedReader
,它可以让你用 readLine()
方法读取整行。不幸的是,这个类不接受 Streams
但是 Reader
s,所以我们需要某种适配器将模拟Reader并能够将字节转换为文本。但这就是 InputStreamReader
存在的原因。
因此,让应用程序从输入流中读取数据的代码看起来像
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print(你好。请写下你的名字:);
String name = br.readLine();
System.out.println(你的名字是:+名字);
首选/最简单的解决方案 - 扫描仪
要避免将 magic 转换为允许将Stream转换为Reader,您可以使用 Scanner
类,该类用于从Streams和Readers中读取数据作为文本。
这意味着您只需使用
扫描仪扫描仪=新扫描仪(System.in);
// ... ...
String name = scanner.nextLine();
从用户读取数据(由IDE使用标准输入流模拟的控制台发送)。
I have just started learning Java with IntelliJ IDE. I know a bit C# so the logic makes some sense, however there is one thing so far I couldn't get over it.
How do I read from the console? In C#, you could easily read what the human typed into it, using Console.ReadLine()
. In Java, System.console().readLine();
does not work for me and throws a NullPointerException
.
What am I missing here?
Problem
Most IDEs are using javaw.exe
instead of java.exe
to run Java code (see image below).
Difference between these two programs is that javaw
runs Java code without association with current terminal/console (which is useful for GUI applications), and since there is no associated console window System.console()
returns null
. Because of that System.console().readLine()
ends up as null.readLine()
which throws NullPointerException
since null
doesn't have readLine()
method (nor any method/field).
But just because there is no associated console, it doesn't mean that we can't communicate with javaw
process. This process still supports standard input/output/error streams, so IDEs process (and via it also we) can use them via System.in
, System.out
and System.err
.
This way IDEs can have some tab/window and let it simulate console.
For instance when we run code like in Eclipse:
package com.stackoverflow;
public class Demo {
public static void main(String[] args) throws Exception {
System.out.println("hello world");
System.out.println(System.console());
}
}
we will see as result
which shows that despite javaw.exe
not having associated console (null
at the end) IDE was able to handle data from standard output of the javaw
process System.out.println("hello world");
and show hello world
.
General solution
To let user pass information to process use standard input stream (System.in
). But since in
is simple InputStream
and Stream
s are meant to handle binary data it doesn't have methods which would let it easily and properly read data as text (especially if encoding can be involved). That is why Readers
and Writers
ware added to Java.
So to make life easier and let application read data from user as text you can wrap this stream in one of the Reader
s like BufferedReader
which will let you read entire line with readLine()
method. Unfortunately this class doesn't accept Streams
but Reader
s, so we need some kind of adapter which will simulate Reader and be able to translate bytes to text. But that is why InputStreamReader
exists.
So code which would let application read data from input stream could look like
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);
Preferred/simplest solution - Scanner
To avoid this magic involving converting Stream to Reader you can use Scanner
class, which is meant to read data as text from Streams and Readers.
This means you can simply use
Scanner scanner = new Scanner(System.in);
//...
String name = scanner.nextLine();
to read data from user (which will be send by console simulated by IDE using standard input stream).
这篇关于试图用Java从控制台读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!