【问题标题】:Parse Standard Output on Thread在线程上解析标准输出
【发布时间】:2021-11-15 18:45:16
【问题描述】:

我想启动一个新线程来处理标准输出,并检查每一行是否包含字符串Success!。这就是我所拥有的:

final Thread ioThread = new Thread(() -> {
    try {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.out));
        String line;
        while ((line = reader.readLine()) != null) {
            if (line.contains("Success!")) {
                // FOUND LINE!!
            }
        }
        reader.close();
    } catch (final Exception e) {
        e.printStackTrace();
    }
});
ioThread.start();

问题在于InputStreamReader 构造函数需要InputStream,而不是PrintStream。我该如何解决这个问题?

【问题讨论】:

  • 一个 PrintStream 用于输出
  • 可能有比程序尝试解析自己的标准输出更好的方法来发现某事已成功完成。虽然现在我只能建议你用你自己的实现替换 out 尝试解析通过它写入的所有内容,除此之外将所有字节路由到默认输出流。
  • #1 你的应用是rest api还是桌面应用? #2 你想听你的应用程序的所有标准输出(System.out.println("hello"))吗?通常我们需要另一个进程的标准输出,而不是应用程序本身
  • 将 System.out 更改为 System.in。您无法从 OutputStream 中读取数据。

标签: java stdout


【解决方案1】:

我认为如果您更详细地描述您需要实现的目标会更好,因为可能有更简单的方法来处理这个问题。

但是,可以通过调用System.setOut(newOut) 扫描您的进程自己的标准输出,用合适的间谍流替换默认输出。

此调用spy() 使用连接到PipedInputStreamPipedOutputStream 调整System.out,以在后台线程中执行扫描,该线程还将输出发送回真实的System.out

private static void spy() throws IOException {
    PipedOutputStream out = new PipedOutputStream();
    PipedInputStream in = new PipedInputStream(out);

    PrintStream sOut = System.out;

    System.setOut(new PrintStream(out));
    final Thread ioThread = new Thread(() -> {
        try(BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
            String line;
            while ((line = reader.readLine()) != null) {

                // Send line to real System.out:
                sOut.println(line);

                if (line.contains("Success!")) {
                    // FOUND LINE!!
                    System.err.println("=== Found a match: "+line);
                }
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    });
    ioThread.start();
}

这个测试程序展示了它是如何工作的。

public static void main(String[] args) throws IOException {
    spy();

    String s = """
            one
            two
            three Success!
            four
            """;

    System.out.println(s);
    System.out.close();
}

打印:

one
two
three Success!
=== Found a match: three Success!
four

请注意,有一个缺点是您的主程序必须关闭System.out,否则间谍线程不知道主应用程序何时完成编写 - 否则您将需要在管道中处理java.io.IOException: Write end dead

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-09
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多