2009-06-30 7 views
83

ユーザーがJavaで入力する際に​​、コンソールから1つの文字を読み込む簡単な方法はありますか?出来ますか?私は、これらの方法で試してみたが、それらはすべてキーを入力押して、ユーザを待た:Javaでコンソールから1つの文字を読み取る方法(ユーザーが入力した場合)?

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

答えて

50

「調理」モードではなくコンソールを「生」モード(行編集をバイパスし、入力キーは必要ありません)にします(Enterキーを使った行編集が必要です)。UNIXシステムでは、 stty 'コマンドはモードを変更できます。

Javaに関しては、Non blocking console input in Python and Javaを参照してください。抜粋:

あなたのプログラムがベースのコンソールでなければならない場合は、文字モードにラインモードの をあなたの端末を切り替え、 あなた プログラムが終了する前にそれを復元するために覚えておく必要があり 。 システムでは、これを行うためのポータブル機器はありません。

JNIを使​​用することをお勧めします。再び、それはあまり移植性がありません。スレッドの終わりに、そして上記のポストと共通する別の提案は、jCursesを使用して調べることです。

+4

JCursesは非常に移植されていないか.... JCursesのREADMEから:「JCursesは2つの部分で構成されていますplattform独立した部分、 とplattform依存最初の部分で利用可能なプリミティブな入出力操作を行うネイティブ共有ライブラリで構成されています。 –

+2

@RyanFernandesは私にはかなり移植性があります。複数のシステム(異なる依存関係を使用して)で実行できる1つのツールです。 – Antoniossss

20

コンソールをrawモードにする必要があります。プラットフォームに依存しない方法で組み込むことはできません。 jCurses might be interesting, though. UNIXシステム上

、これはうまくいくかもしれない:

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

For example, if you want to take into account the time between keystrokes, here's sample code to get there.

+0

Linuxの下でうまく動作しました。 – MrSmith42

+0

Macでも動作します。 'stty cooked Kelvin

+0

「例の...」リンクが死んでいます。 –

13

Javaコンソールからの生の文字を読むために何の移植方法はありません。

一部のプラットフォームに依存した回避策が上記に示されています。しかし、本当に移植可能なようにするには、コンソールモードを放棄してウィンドウモードを使用する必要があります。 AWTまたはSwing。

+11

私はMono(またはCLR)がすべてのプラットフォームで動作する 'System.Console.ReadKey'を持っている理由をよく理解していません。また、Javaは、プラットフォームに依存するライブラリと実装を持つすべてのプラットフォームに対してJVMとJREを配布します。したがって、それは言い訳ではありません。 –

6

JNAを使用してWindowsおよびUnix/Linuxのオペレーティングシステム機能を呼び出すJavaクラスRawConsoleInputを作成しました。

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

これは、ノンブロッキング入力とミックス生モードとノーマルラインモード入力をサポートしています。

+0

これは、テスト/ストレステストの重大度をどの程度持っていますか? –

+1

@QPaysTaxesコンソール入力のストレステストは難しいです。私はこのケースでは、さまざまな環境(異なるWindows/Linuxバージョン、64/32ビット、SSH、Telnet、シリアルポートまたはデスクトップコンソールなどのLinux)でテストすることがより重要になると考えています。これまで私は私の個人的なテストツールでしか使用していません。しかし、他のソリューション(Jansiを使用するJLine2など)と比べて、ソースコードは比較的小さいです。だから間違ってしまうことはあまりありません。私はそれを書いています.JLine2はブロックせずに1文字入力をサポートしていないからです。 –

+0

それは私がストレステストした意味です - おそらく間違った言葉です。私の悪い。とにかく、素敵!私は盗んだ^ H^H^H^H^H ^学校のために私のプロジェクトでそれを凌駕し、束を助けた。 –

0

使用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();