web-dev-qa-db-ja.com

Javaでコンソールから単一の文字を読み取る方法(ユーザーが入力したとおり)

ユーザーがJavaで入力しているときにコンソールから単一の文字を読み取る簡単な方法はありますか?出来ますか?私はこれらの方法を試しましたが、ユーザーがenterキーを押すのを待ちます:

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は、enterが押されるまでユーザー入力を認識しないと考え始めています。

100
victor hugo

あなたがしたいことは、コンソールを「生」モード(行編集をバイパスし、Enterキーは不要)にすることです(「調理」モード(Enterキーを使用した行編集が必要)。)UNIXシステムでは、 'stty'コマンドはモードを変更します。

さて、Javaに関しては、 PythonおよびJavaでの非ブロッキングコンソール入力 を参照してください。抜粋:

プログラムがコンソールベースでなければならない場合、端末をラインモードからキャラクターモードに切り替え、プログラムが終了する前にそれを復元することを忘れないでください。オペレーティングシステム間でこれを実行する移植可能な方法はありません。

提案の1つは、JNIを使​​用することです。繰り返しますが、それはあまり移植性がありません。スレッドの最後で、上記の投稿と共通するもう1つの提案は、 jCurses を使用することです。

57
Chris W. Rea

コンソールをrawモードにノックする必要があります。プラットフォームに依存しない組み込みの方法はありません。 jCurses は興味深いかもしれません。

Unixシステムでは、これが機能する場合があります。

String[] cmd = {"/bin/sh", "-c", "stty raw </dev/tty"};
Runtime.getRuntime().exec(cmd).waitFor();

たとえば、キーストローク間の時間を考慮したい場合、そこに到達するためのサンプルコードがあります。

23
nes1983

Javaコンソールから生の文字を読み取るための移植可能な方法はありません。

プラットフォームに依存する回避策がいくつか上に提示されています。しかし、本当に移植性を高めるには、コンソールモードを放棄して、ウィンドウモードを使用する必要があります。 AWTまたはSwing。

14
rustyx

Javaクラスを記述しました RawConsoleInputJNA を使用して、WindowsおよびUnix/Linuxのオペレーティングシステム関数を呼び出します。

  • Windowsでは、msvcrt.dllの_kbhit()および_getwch()を使用します。
  • Unixでは、tcsetattr()を使用してコンソールを非標準モードに切り替え、System.in.available()を使用してデータが使用可能かどうかを確認し、System.in.read()を使用してコンソールからバイトを読み取ります。 CharsetDecoderは、バイトを文字に変換するために使用されます。

ノンブロッキング入力と、rawモードと通常のラインモード入力の混合をサポートしています。

13

jline を使用します。

例:

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();
6
Pod