Как прочитать один символ с консоли на Java (как пользователь его вводит)?
Есть ли простой способ прочитать один символ из консоли, когда пользователь печатает его на Java? Является ли это возможным? Я пробовал с этими методами, но все они ждут, пока пользователь нажмет клавишу ввода:
char tmp = (char) System.in.read();
char tmp = (char) new InputStreamReader(System.in).read ();
char tmp = (char) System.console().reader().read(); // Java 6
Я начинаю думать, что System.in не знает о пользовательском вводе, пока не будет нажата кнопка ввода.
7 ответов
То, что вы хотите сделать, это перевести консоль в "сырой" режим (обведение строки обойдено и ключ ввода не требуется), в отличие от "готового" режима (редактирование строки с ключом ввода.) В системах UNIX команда 'stty' может смена режимов.
Теперь относительно Java... см. Неблокирующая консольная запись в Python и Java. Выдержка:
Если ваша программа должна быть основана на консоли, вы должны переключить свой терминал из линейного режима в символьный режим, и не забудьте восстановить его до выхода из программы. Нет переносимого способа сделать это в операционных системах.
Одним из предложений является использование JNI. Опять же, это не очень портативно. Еще одно предложение в конце ветки, как и в предыдущем посте, заключается в использовании jCurses.
Вам нужно перевести вашу консоль в сырой режим. Нет встроенного независимого от платформы способа добраться туда. Хотя курсы могут быть интересными.
В системе Unix это может работать:
String[] cmd = {"/bin/sh", "-c", "stty raw </dev/tty"};
Runtime.getRuntime().exec(cmd).waitFor();
Например, если вы хотите учесть время между нажатиями клавиш, вот пример кода, чтобы добраться туда.
Я написал Java-класс RawConsoleInput, который использует JNA для вызова функций операционной системы Windows и Unix/Linux.
- На Windows это использует
_kbhit()
а также_getwch()
из msvcrt.dll. - На Unix он использует
tcsetattr()
переключить консоль в неканонический режим,System.in.available()
проверить, доступны ли данные иSystem.in.read()
читать байты из консоли.CharsetDecoder
используется для преобразования байтов в символы.
Он поддерживает неблокирующий ввод и смешивание исходного режима и нормального ввода в линейном режиме.
Не существует переносимого способа чтения необработанных символов с консоли Java.
Некоторые зависящие от платформы обходные пути были представлены выше. Но чтобы быть действительно переносимым, вам придется отказаться от консольного режима и использовать оконный режим, например AWT или Swing.
Используйте jline3:
Пример:
Terminal terminal = TerminalBuilder.builder()
.jna(true)
.system(true)
.build();
// raw mode means we get keypresses rather than line buffered input
terminal.enterRawMode();
reader = terminal .reader();
...
int read = reader.read();
....
reader.close();
terminal.close();
Я сделал это с помощью jcurses...
import jcurses.system.InputChar;
import jcurses.system.Toolkit;
//(works best on the local machine when run through screen)
public class readchar3 {
public static void main (String[] args)
{
String st;
char ch;
int i;
st = "";
ch = ' ';
i = 0;
while (true)
{
InputChar c = Toolkit.readCharacter();
ch = c.getCharacter();
i = (int) ch;
System.out.print ("you typed " + ch + "(" + i + ")\n\r");
// break on '#'
if (ch == '#') break;
}
System.out.println ("Programm wird beendet. Verarbeitung kann beginnen.");
}
}
Он вызывает функцию _getch() из c для чтения одного символа без нажатия Enter.