Почему мы не можем прочитать один символ за раз из System.in? - PullRequest
18 голосов
/ 24 октября 2010

Программа, приведенная ниже, печатает каждый символ, написанный на стандартном языке in, но только после написания новой строки (по крайней мере, в моей системе!).

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

Это мешает людям писать что-то вроде «Нажмите любую клавишу для продолжения» и вызывает что-то вроде «Нажмите ввод для продолжения».

  • Что является основной причиной этого?
  • Это ограничение Java?
  • Это поведение зависит от системы (я нахожусь на Ubuntu)? Как это работает на Mac? Окна
  • Зависит ли это от конкретного терминала, в котором я запускаю приложение? (Для меня это ведет себя так в Eclipse и в gnome-Terminal)
  • Есть ли обходной путь?

Ответы [ 3 ]

19 голосов
/ 24 октября 2010

Что является основной причиной этого?

Большинство терминалов по умолчанию являются буферизованными строками, Java не получает ввод до новой строки.

Это ограничение Java?

Некоторые древние терминалы могут иметь только линейный вход; хотя в большинстве современных терминалов должна быть возможность отключить буферизацию.

Это поведение зависит от системы (я нахожусь на Ubuntu)? Как это работает на Mac? Окна

Да.

Зависит ли это от конкретного терминала, в котором я запускаю приложение? (Для меня это ведет себя так в Eclipse и в gnome-Terminal)

Да.

Есть ли обходной путь?

Есть хаки для платформ. curse в Linux и Unix-подобных платформах и getch () в Windows. Я не знаю ни о каком кроссплатформенном способе.

related : Почему «Нажмите любую клавишу для продолжения» - плохая идея:

alt text

6 голосов
/ 18 января 2015

Я нахожусь на Ubuntu

Есть ли обходной путь?

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

И после этого все чтения System.in в одном процессе будут читать 1персонаж не ждет EOL.

0 голосов
/ 12 апреля 2012

см. Мой ответ в Эквивалентная функция для "_getch ()" C в Java?


public static void getCh() {</p>

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

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...