java - 如何在 Linux 终端上从 Java 标准输入中抑制或删除转义码字符

标签 java terminal stdin

我在这里和其他地方做了一些涉及这个问题主题的研究,并且我发现了 jline3,它看起来确实是一个清晰的解决方案,并且提供了大量重要的跨平台优势和功能。

但是,作为更好地理解 Java 如何使用流读取器和输入(包括原始字节)以及在 Linux 终端中实现基于文本的基本冒险游戏的一种方法,我希望能够在用户输入时从 stdin 中抑制或删除箭头键转义码。

这似乎不可能通过 Scanner 实现,而且我不确定如何使用 Java 将终端置于原始输入模式 - 如果有办法通过 shell 脚本实现这一点,到目前为止我还无法找到方法。我正在使用一个基本的 shell 脚本来调用我的 Java 程序并传入一些系统属性,因此这也是一个很好的解决方案。

到目前为止,我已经使用了 ByteBufferCharBufferDecoder 等的组合,我从其他问题和一些初步研究中看到了这些组合,但无法实现我想要的目标。

如何才能让我的 Java 程序等待用户输入而不显示或捕获箭头键转义字符(例如 ^[[A^[[B])?

感谢您提供任何帮助或其他资源以供研究。

编辑/更新:

感谢所有对此问题作出答复的人。最终,我正在开发一个几乎完全符合我想要的解决方案,它是 Java Console 类及其正则表达式功能的组合。

下面是一个非常基本的框架。本质上,我选择了排除所有,包括一些方法,其中所有字符都被禁止,但我编译成模式的字符允许打印到屏幕上。

这还让我可以测试其他重要的输入键,例如 Enter 来进入和退出游戏的命令模式,因为我希望游戏对“移动”键使用react,并让用户能够按 Enter 并键入一些命令。

我必须摆弄 stty 才能实现此解决方案,并且 Java 应用程序是通过 bash 脚本启动的。

Bash 脚本:

#!/bin/bash

# Save current terminal settings
STTY_SAVE=$(stty -g)

# Disable need to press [Enter] in order to have input processed
stty cbreak
# Disable the echoing of input
stty -echo
# Tell the terminal that erasure on the console should produce a backspace cursor movement
stty erase ^H

# Execute application
java reader_testing.Main

# Restore saved terminal settings
stty $STTY_SAVE
exit 0

注意:stty删除^H似乎也允许Java中的Console捕获*nix操作系统上的退格键字符代码\010。如果没有该行,它似乎会执行删除(?)

Java 代码:

Console console = System.console();    

int symbol = 0;
char character = 0;

String matchString = new String();
StringBuilder input = new StringBuilder();

Pattern allowed = Pattern.compile( "[a-z0-9 !@#$%^&*()_+-=]" );
Matcher matcher = null;

while ( true ) { // This is an arbitrary loop for the example
    try {
        symbol = console.reader().read();

        if ( symbol == 10 ) { // 10 = Enter
            break;
        }

        character = (char) symbol;

        matchString = Character.toString( character );

        matcher = allowed.matcher( matchString );

        if ( matcher.find() ) {
            input.append( character );

            System.out.print( "\r" + input );
        }
    } catch ( IOException e ) {
        e.printStackTrace();
    }
}

System.out.println( "\nYou entered: " + input );

问题:

  1. 仍在开发退格功能,用“空”字符(例如 char c = 0;)重写输入 StringBuilder 对象的字符并调整其大小。这最终可能根本不起作用。

  2. 我无法找到一种方法来排除大写 A、B、C 和 D,这些字母遵循表示箭头键的转义码序列,因此我不得不禁止所有大写字母。我尝试等到阅读器检测到不再有输入,然后解析该输入,但未能成功实现。

  3. 特殊键(例如“插入”和“删除”)会生成包含仍会打印的数字的字符代码。我还不确定如何在不禁止数字的情况下防止这种情况发生(与箭头键和大写字母的问题相同)。

最后,这些都可能不起作用或者受到相当的限制,但是玩这个很有趣,如果最坏的情况发生,我可以让退格键删除整个输入字符串。输入命令并不是游戏的主要部分。

最佳答案

您可以使用 java.io.Console 类。 Console.writer() 自动处理底层字符编码。 Console.readLine() 从用户处检索一行文本,并等待他按 Enter 键终止。还有许多其他方法可以帮助您制作命令行游戏。

关于java - 如何在 Linux 终端上从 Java 标准输入中抑制或删除转义码字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51993555/

相关文章:

python - 从管道读取 Python 标准输入,不阻塞空输入

java - 数组索引越界异常合并排序过程Java

java - 接受终端命令的设计模式

c++ - 如何在 Mac 上自动获取 C++ 程序的异常类型和消息?

c++ - 在 Ubuntu 的终端上运行 C++ 文件

C 读取二进制标准输入

将缓冲区转换为 8 位值数组并返回 C

java - 使用布局 XML 文件的逻辑

Java多线程: program sporadically strats using more cores than a FixedThreadPool is allowed to

java - 使用Java Servlet在HDFS内创建目录