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

☆樱花仙子☆ 提交于 2019-11-26 09:53:03

问题


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.\"

  • 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?

回答1:


What is the underlying reason for this?

Most terminals is line buffered by default, Java does not receive input until a newline.

Is it a limitation of 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?

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)

Yes.

Is there a workaround?

There are platform specific hacks. curse in Linux and Unix-like platforms, and getch() in Windows. I'm not aware of any cross-platform way.

related: Why "Press any key to continue" is bad idea:




回答2:


I'm on Ubuntu

Is there a workaround?

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.




回答3:


see my answer in 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) {  
    }  
}  

}



来源:https://stackoverflow.com/questions/4007534/why-cant-we-read-one-character-at-a-time-from-system-in

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!