java 为什么我们不能从 System.in 一次读取一个字符?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4007534/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't we read one character at a time from System.in?
提问by aioobe
The program below prints each character written on standard in, but only after a new-line has been written (at least on my system!).
下面的程序打印在标准输入中写入的每个字符,但仅在写入换行符之后(至少在我的系统上!)。
public class Test {
public static void main(String[] args) throws java.io.IOException {
int c;
while ((c = System.in.read()) != -1)
System.out.print((char) c);
}
}
This prevents people from writing stuff like "Press any key to continue" and forces something like "Press enter to continue."
这可以防止人们编写诸如“按任意键继续”之类的内容,并强制执行“按 Enter 继续”之类的内容。
- What is the underlying reason for this?
- Is it a limitation of Java?
- Is this behavior system-dependent (I'm on Ubuntu)? How does it work on Mac? Windows?
- Is it dependent on the specific terminal I run the application in? (For me it behaves like this in Eclipse and in gnome-terminal)
- Is there a workaround?
- 这背后的原因是什么?
- 这是Java的限制吗?
- 这种行为是否依赖于系统(我在 Ubuntu 上)?它在 Mac 上是如何工作的?视窗?
- 它是否取决于我运行应用程序的特定终端?(对我来说,它在 Eclipse 和 gnome-terminal 中的行为是这样的)
- 有解决方法吗?
回答by Lie Ryan
What is the underlying reason for this?
这背后的原因是什么?
Most terminals is line buffered by default, Java does not receive input until a newline.
大多数终端默认是行缓冲的,Java 直到换行才接收输入。
Is it a limitation of Java?
这是Java的限制吗?
Some ancient terminals might only have line-buffered input; though it should be possible to disable buffering in most modern terminal.
一些古老的终端可能只有行缓冲输入;尽管应该可以在大多数现代终端中禁用缓冲。
Is this behavior system-dependent (I'm on Ubuntu)? How does it work on Mac? Windows?
这种行为是否依赖于系统(我在 Ubuntu 上)?它在 Mac 上是如何工作的?视窗?
Yes.
是的。
Is it dependent on the specific terminal I run the application in? (For me it behaves like this in Eclipse and in gnome-terminal)
它是否取决于我运行应用程序的特定终端?(对我来说,它在 Eclipse 和 gnome-terminal 中的行为是这样的)
Yes.
是的。
Is there a workaround?
有解决方法吗?
There are platform specific hacks. cursein Linux and Unix-like platforms, and getch() in Windows. I'm not aware of any cross-platform way.
有特定于平台的黑客。curse在 Linux 和类 Unix 平台中,以及在 Windows 中的 getch()。我不知道任何跨平台的方式。
related: Why "Press any key to continue" is bad idea:
相关:为什么“按任意键继续”是个坏主意:


回答by hoat4
I'm on Ubuntu
Is there a workaround?
我在 Ubuntu
有解决方法吗?
Runtime.getRuntime().exec("stty -icanon min 1").waitFor();
And after that all reads of System.in in the same process will read 1 character not waiting for EOL.
之后在同一进程中对 System.in 的所有读取将读取 1 个字符,而不是等待 EOL。
回答by Nagaraju Badaeni
see my answer in Equivalent function to C's "_getch()" in Java?
看到我在 Java 中 C 的“_getch()”的等效函数中的回答?
public static void getCh() {
final JFrame frame = new JFrame();
synchronized (frame) {
frame.setUndecorated(true);
frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
frame.addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
synchronized (frame) {
frame.setVisible(false);
frame.dispose();
frame.notify();
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
});
frame.setVisible(true);
try {
frame.wait();
} catch (InterruptedException e1) {
}
}
}
}

