如何从 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 在按下 进来之前不知道用户输入。

160583 次浏览

您想要做的是将控制台设置为“原始”模式(忽略行编辑,不需要输入键) ,而不是“熟”模式(需要输入键的行编辑)在 UNIX 系统上,“ stty”命令可以更改模式。

现在,关于 Java... ... 请参阅 Python 和 Java 中的非阻塞控制台输入:

如果您的程序必须基于控制台, 你必须把你的终端关掉 行模式转换为字符模式,以及 记得在你的 程序退出,没有便携程序 通过手术来达到这个目的 系统。

其中一个建议是使用 JNI。再说一次,这不是很便携。另一个在线程末尾的建议,和上面的文章一样,是考虑使用 诅咒

您需要将控制台调到原始模式。没有内置的独立于平台的方法可以实现这一目标。不过 诅咒可能会很有趣。

在 Unix 系统上,这可能行得通:

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

例如,如果您想考虑击键之间的时间,这里有一些示例代码。

没有从 Java 控制台读取原始字符的可移植方法。

上面已经介绍了一些与平台相关的工作区。但是要真正便携,您必须放弃控制台模式,使用窗口模式,例如 AWT 或 Swing。

我编写了一个 Java 类 RawConsole 输入,它使用 JNA调用 Windows 和 Unix/Linux 的操作系统函数。

  • 在 Windows 上,它使用 msvcrt.dll 中的 _kbhit()_getwch()
  • 在 Unix 上,它使用 tcsetattr()将控制台切换到非规范模式,使用 System.in.available()检查数据是否可用,使用 System.in.read()从控制台读取字节。CharsetDecoder用于将字节转换为字符。

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

使用 Jline 3:

例如:

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