【问题标题】:How to flter ANSI/Terminal Control sequences from InputStream?如何从 InputStream 中过滤 ANSI/终端控制序列?
【发布时间】:2022-03-17 18:03:05
【问题描述】:

我正在使用pty4j 库构建一个简单的终端仿真器。我的程序有一个 print() 方法,它使用 javafx 中的 GraphicsContext.fillText() 方法将文本呈现到画布上。我将模拟器连接到 cmd 实例并从缓冲读取器读取输出。现在可悲的是,当它收到文本时,它还包括ANSI-escape characters(见图)。但是,如果我将输出打印到 IDE 或系统控制台,它可以正常工作。

我尝试使用 BufferedReader 中的 readLine() 方法,然后应用正则表达式,但因为并非所有从终端收到的输入都被 \n 终止,它在最后一行阻塞。

Thread terminalReaderThread = new Thread() {
   public void run() {
      try {
         int c;
         while (terminal.isRunning() && (c = terminal.getReader().read()) != -1) {
            if(c != 0){
               print(Character.toString((char)c));
            }
         }

      } catch (IOException e) {
         e.printStackTrace();
      }
  }
};
terminalReaderThread.start();

有没有有效的方法从 inputStream 中过滤掉这些转义码?

【问题讨论】:

  • 你只需要给自己写一个FilterReader子类来解决这个问题。
  • @user207421 一些控制序列有多个字符长。 FilterReader 怎么可能?
  • 根据您的需要,您可能会摆脱复杂的正则表达式过滤。由于这很容易出错(某些序列可以交错),因此更好的方法是通过终端解析器来识别序列。

标签: java inputstream ansi xterm terminal-emulator


【解决方案1】:

我收到的问题 (Safely ignoring unknown ANSI, ESC/P, ESC/POS sequences, know the length) 的答案也应该能回答您的问题。 如果您阅读标准 (ECMA-48 https://www.ecma-international.org/wp-content/uploads/ECMA-48_5th_edition_june_1991.pdf),您将看到序列始终从 ESCAPE 字符开始,并始终以具有定义范围内的值的 FINAL BYTE 结束。 有了这些信息,就足以检测每个序列的开始和结束。 (例如正则表达式)(换行符(和其他 C0 代码)也不允许在转义序列内,因此您永远不会有一个不完全位于一行内的转义序列)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    • 2013-11-02
    • 2014-09-26
    • 1970-01-01
    相关资源
    最近更新 更多