如何在Java中从控制台读取单个字符(用户键入它)?

时间:2022-06-11 20:45:22

Is there an easy way to read a single char from the console as the user is typing it in Java? Is it possible? I've tried with these methods but they all wait for the user to press enter key:

当用户在Java中键入时,是否有一种从控制台读取单个字符的简单方法?可能吗?我尝试过这些方法但他们都在等待用户按下回车键:

char tmp = (char) System.in.read();
char tmp = (char) new InputStreamReader(System.in).read ();
char tmp = (char) System.console().reader().read();           // Java 6

I'm starting to think that System.in is not aware of the user input until enter is pressed.

我开始认为System.in在按下enter之前不知道用户输入。

5 个解决方案

#1


50  

What you want to do is put the console into "raw" mode (line editing bypassed and no enter key required) as opposed to "cooked" mode (line editing with enter key required.) On UNIX systems, the 'stty' command can change modes.

您想要做的是将控制台置于“原始”模式(绕过行编辑并且不需要输入键),而不是“熟”模式(需要使用输入键进行行编辑。)在UNIX系统上,'stty'命令可以改变模式。

Now, with respect to Java... see Non blocking console input in Python and Java. Excerpt:

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

If your program must be console based, you have to switch your terminal out of line mode into character mode, and remember to restore it before your program quits. There is no portable way to do this across operating systems.

如果您的程序必须基于控制台,则必须将终端脱机模式切换到字符模式,并记住在程序退出之前恢复它。在操作系统中没有可移植的方法。

One of the suggestions is to use JNI. Again, that's not very portable. Another suggestion at the end of the thread, and in common with the post above, is to look at using jCurses.

其中一个建议是使用JNI。再说一次,这不是很便携。线程末尾的另一个建议,与上面的帖子一样,是使用jCurses。

#2


20  

You need to knock your console into raw mode. There is no built-in platform-independent way of getting there. jCurses might be interesting, though.

您需要将控制台敲入原始模式。没有内置的平台无关的方式。但是jcurses可能很有趣。

On a unix system, this might work:

在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.

例如,如果您想要考虑击键之间的时间,可以参考下面的示例代码。

#3


13  

There is no portable way to read raw characters from a Java console.

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

Some platform-dependent workarounds have been presented above. But to be really portable, you'd have to abandon console mode and use a windowing mode, e.g. AWT or Swing.

上面已经介绍了一些与平台相关的变通方法。但要真正便携,你必须放弃控制台模式并使用窗口模式,例如AWT或Swing。

#4


9  

I have written a Java class RawConsoleInput that uses JNA to call operating system functions of Windows and Unix/Linux.

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

  • On Windows it uses _kbhit() and _getwch() from msvcrt.dll.
  • 在Windows上,它使用msvcrt.dll中的_kbhit()和_getwch()。
  • On Unix it uses tcsetattr() to switch the console to non-canonical mode, System.in.available() to check whether data is available and System.in.read() to read bytes from the console. A CharsetDecoder is used to convert bytes to characters.
  • 在Unix上,它使用tcsetattr()将控制台切换到非规范模式,System.in.available()用于检查数据是否可用,System.in.read()用于从控制台读取字节。 CharsetDecoder用于将字节转换为字符。

It supports non-blocking input and mixing raw mode and normal line mode input.

它支持无阻塞输入和混合原始模式和普通线路模式输入。

#5


4  

Use jline3:

使用jline3:

Example:

例:

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

#1


50  

What you want to do is put the console into "raw" mode (line editing bypassed and no enter key required) as opposed to "cooked" mode (line editing with enter key required.) On UNIX systems, the 'stty' command can change modes.

您想要做的是将控制台置于“原始”模式(绕过行编辑并且不需要输入键),而不是“熟”模式(需要使用输入键进行行编辑。)在UNIX系统上,'stty'命令可以改变模式。

Now, with respect to Java... see Non blocking console input in Python and Java. Excerpt:

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

If your program must be console based, you have to switch your terminal out of line mode into character mode, and remember to restore it before your program quits. There is no portable way to do this across operating systems.

如果您的程序必须基于控制台,则必须将终端脱机模式切换到字符模式,并记住在程序退出之前恢复它。在操作系统中没有可移植的方法。

One of the suggestions is to use JNI. Again, that's not very portable. Another suggestion at the end of the thread, and in common with the post above, is to look at using jCurses.

其中一个建议是使用JNI。再说一次,这不是很便携。线程末尾的另一个建议,与上面的帖子一样,是使用jCurses。

#2


20  

You need to knock your console into raw mode. There is no built-in platform-independent way of getting there. jCurses might be interesting, though.

您需要将控制台敲入原始模式。没有内置的平台无关的方式。但是jcurses可能很有趣。

On a unix system, this might work:

在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.

例如,如果您想要考虑击键之间的时间,可以参考下面的示例代码。

#3


13  

There is no portable way to read raw characters from a Java console.

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

Some platform-dependent workarounds have been presented above. But to be really portable, you'd have to abandon console mode and use a windowing mode, e.g. AWT or Swing.

上面已经介绍了一些与平台相关的变通方法。但要真正便携,你必须放弃控制台模式并使用窗口模式,例如AWT或Swing。

#4


9  

I have written a Java class RawConsoleInput that uses JNA to call operating system functions of Windows and Unix/Linux.

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

  • On Windows it uses _kbhit() and _getwch() from msvcrt.dll.
  • 在Windows上,它使用msvcrt.dll中的_kbhit()和_getwch()。
  • On Unix it uses tcsetattr() to switch the console to non-canonical mode, System.in.available() to check whether data is available and System.in.read() to read bytes from the console. A CharsetDecoder is used to convert bytes to characters.
  • 在Unix上,它使用tcsetattr()将控制台切换到非规范模式,System.in.available()用于检查数据是否可用,System.in.read()用于从控制台读取字节。 CharsetDecoder用于将字节转换为字符。

It supports non-blocking input and mixing raw mode and normal line mode input.

它支持无阻塞输入和混合原始模式和普通线路模式输入。

#5


4  

Use jline3:

使用jline3:

Example:

例:

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