为什么我们不能一次从System.in读取一个字符?

时间:2010-10-24 08:27:38

标签: java stdin

下面的程序会打印标准写入的每个字符,但只能在写完新行之后(至少在我的系统上!)。

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

这可以防止人们写“按任意键继续”之类的内容并强制执行“按Enter键继续”等内容。

  • 这是什么原因?
  • 这是Java的限制吗?
  • 这种行为是否与系统有关(我在Ubuntu上)?它在Mac上如何运作?窗口?
  • 是否依赖于我运行应用程序的特定终端? (对我来说,它在Eclipse和gnome-terminal中表现得像这样)
  • 有解决方法吗?

3 个答案:

答案 0 :(得分:19)

  

这是什么原因?

默认情况下,大多数终端都是行缓冲的,Java在换行之前不会接收输入。

  

这是Java的限制吗?

一些古老的终端可能只有线路缓冲输入;虽然应该可以在大多数现代终端中禁用缓冲。

  

这种行为依赖于系统(我在Ubuntu上)吗?它在Mac上如何运作?视窗?

  

它是否依赖于我运行应用程序的特定终端? (对我来说,它在Eclipse和gnome-terminal中表现得像这样)

  

有解决方法吗?

有特定于平台的黑客攻击。 Linux和类Unix平台中的curse和Windows中的getch()。我不知道任何跨平台的方式。

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

alt text

答案 1 :(得分:6)

  

我在Ubuntu上

     

有解决方法吗?

Runtime.getRuntime().exec("stty -icanon min 1").waitFor();

之后,在同一进程中对System.in的所有读取将读取1个字符,而不是等待EOL。

答案 2 :(得分:0)

Equivalent function to C's "_getch()" in Java?

中查看我的回答


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

}