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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 04:20:46  来源:igfitidea点击:

Why can't we read one character at a time from System.in?

javastdin

提问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:

相关:为什么“按任意键继续”是个坏主意:

alt text

替代文字

回答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) { } }

}

}