提问人:victor hugo 提问时间:7/1/2009 最后编辑:Thomas Ahlevictor hugo 更新时间:10/7/2021 访问量:164616
如何在 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();
例如,如果要考虑击键之间的时间,下面是实现该目标的示例代码。
评论
stty cooked </dev/tty
没有可移植的方法来从 Java 控制台读取原始字符。
上面介绍了一些与平台相关的解决方法。但要真正便携,您必须放弃控制台模式并使用窗口模式,例如 AWT 或 Swing。
我编写了一个 Java 类 RawConsoleInput,它使用 JNA 来调用 Windows 和 Unix/Linux 的操作系统函数。
- 在 Windows 上,它使用 和 来自 msvcrt.dll。
_kbhit()
_getwch()
- 在 Unix 上,它用于将控制台切换到非规范模式,检查数据是否可用并从控制台读取字节。A 用于将字节转换为字符。
tcsetattr()
System.in.available()
System.in.read()
CharsetDecoder
它支持无阻塞输入和混音原始模式和正常线路模式输入。
评论
Pointer.SIZE
,因此我们还需要将其替换为 on line 170。Native.POINTER_SIZE
使用 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 键
评论