代码之家  ›  专栏  ›  技术社区  ›  aioobe

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

  •  18
  • aioobe  · 技术社区  · 14 年前

    下面的程序打印标准中写入的每个字符,但必须在写入新行之后(至少在我的系统上!).

    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终端中的行为是这样的)
    • 有解决办法吗?
    3 回复  |  直到 10 年前
        1
  •  19
  •   Lie Ryan Bryan    14 年前

    其根本原因是什么?

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

    它是Java的限制吗?

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

    这个行为系统依赖于(我在Ubuntu上)?它在Mac上是如何工作的?窗户?

    对。

    它是否依赖于运行应用程序的特定终端?(对我来说,它在Eclipse和GNOME终端中的行为是这样的)

    对。

    有解决办法吗?

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

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

    alt text

        2
  •  6
  •   forvaidya    10 年前

    我在Ubuntu

    有解决办法吗?

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

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

        3
  •  0
  •   Community CDub    8 年前

    在中查看我的答案 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) {  
        }  
    }  
    

    }