簡體   English   中英

如何從 Java 中的控制台讀取單個字符(當用戶鍵入時)?

[英]How to read a single char from the console in Java (as the user types it)?

當用戶在 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 在按下輸入之前不知道用戶輸入。

您要做的是將控制台置於“原始”模式(繞過行編輯並且不需要回車鍵)而不是“熟”模式(需要使用回車鍵進行行編輯)。在 UNIX 系統上,“stty”命令可以改變模式。

現在,關於 Java...請參閱Python 和 Java 中的非阻塞控制台輸入 摘抄:

如果您的程序必須基於控制台,您必須將終端從行模式切換到字符模式,並記住在程序退出之前恢復它。 沒有可移植的方法可以跨操作系統執行此操作。

建議之一是使用 JNI。 同樣,這不是很便攜。 線程末尾的另一個建議,與上面的帖子相同,是查看使用jCurses

您需要將控制台敲入原始模式。 沒有內置的獨立於平台的方法可以到達那里。 不過, jCurses可能很有趣。

在 Unix 系統上,這可能有效:

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

例如,如果您想考慮擊鍵之間的時間,這里有示例代碼。

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

  • 在 Windows 上,它使用 msvcrt.dll 中的_kbhit()_getwch()
  • 在 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.");
        }
}

看到這個

它從 c 調用 _getch() 函數來讀取單個字符而不按 Enter

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM