2009-06-30 130 views
83

當用戶使用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不知道用戶輸入的,直到進入是按下。

回答

50

與「熟化」模式相反,您需要做的是將控制檯置於「原始」模式(線路編輯被繞過並且不需要輸入鍵)。在UNIX系統中, stty'命令可以改變模式。

現在,就Java而言......見Non blocking console input in Python and Java。摘錄:

如果你的程序必須是基於控制檯, 你有你的終端的行模式 轉出到字符模式,並 記得你 程序退出之前恢復它。在操作 系統中沒有便攜式的方式來執行此操作。

其中一個建議是使用JNI。再次,這不是很便攜。線程末尾的另一個建議,和上面的帖子一樣,使用jCurses

+4

JCurses不是很便攜式任....從JCurses自述文件:「JCurses由兩個部分組成:獨立plattform部分, 和plattform依賴部分,它由一個本地共享庫組成,它使得原始輸入和輸出操作可用於第一部分。「 – 2009-07-01 03:19:30

+2

@RyanFernandes對我來說聽起來相當隨身攜帶 - 可以在多個系統上運行的單一工具(使用不同的依賴關係) – Antoniossss 2017-10-19 21:56:41

20

您需要將控制檯敲入原始模式。沒有內置平臺無關的方式。 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 2015-10-20 18:03:27

+0

也適用於Mac。你可能想提一下,當程序需要恢復到緩衝模式時,以及在程序退出之前,應該運行`stty cooked Kelvin 2017-05-08 20:21:39

13

有從Java控制檯讀取原始字符沒有可移植的方法。

上面介紹了一些與平臺相關的解決方法。但爲了便於攜帶,你必須放棄控制檯模式並使用窗口模式,例如AWT或Swing。

6

我寫了一個Java類RawConsoleInput,它使用JNA來調用Windows和Unix/Linux的操作系統函數。

  • 在Windows上,它使用msvcrt.dll中的_kbhit()_getwch()
  • 在Unix上,它使用tcsetattr()將控制檯切換到非規範模式,System.in.available()檢查數據是否可用,System.in.read()是否從控制檯讀取字節。 A CharsetDecoder用於將字節轉換爲字符。

它支持非阻塞輸入和混合原始模式和正常線路模式輸入。

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(); 
相關問題