1

所以,我想做的基本上是过滤所有通过的东西,是否System.out可以System.err应用某种过滤器或创建自己的过滤器OutputStream来转移System.out,然后正常处理它?

为清楚起见进行编辑:为了澄清,我需要从其他程序中读取 System.out 的内容并按照我认为合适的方式对其进行操作,因此记录器并不是一个真正的选择,因为我无法控制其他程序将使用什么.

编辑更清楚:我正在为一个更大的程序创建一个插件,该程序需要读取从其他插件写入 System.out 的所有内容。因为它是一个基于插件的系统,所以我的插件运行的进程将始终与其他插件运行的进程相同。

4

3 回答 3

4

我不清楚的事情:你提到你想“从其他程序中读取 System.out 的内容”。您的应用程序是在创建流程并想要监控其标准输出/错误,还是您想要监控流程本身的标准输出/错误?

对于前一种情况,创建流程后,您可以获得其输出输入错误流。

对于后一种情况,您可以通过以下方式替换 Java 进程中的标准System.setOut(yourOwnOutputStream);

但是,如果您正在尝试处理完全不相关的流程流,我相信如果不让调用者将 stdout/stderr 通过管道传输到您的流程(除非通过某些特定于平台的方法),就无法这样做


更新:

为了“拦截”标准输出,它与所有那些经典的“过滤输出流”没有什么不同。你可以做的是这样的:

class AnalyzingOutputStream extends FilterOutputStream {

    public AnalyzingOutputStream (OutputStream out) {
        super(out);
    }

    @Override
    public void write(int b) {
          // do whatever analysis you want
          super.write(b);  // delegate to super class' write, which will 
                           // delegate to the filtered outputstream
    }
    // other overrides
}

为了使用它,您的主要逻辑应该执行以下操作:

AnalyzingOutputStream analyzingOutputStream = new AnalyzingOutputStream(System.out);
System.setOut(analyzingOutputStream );

// then you can call your methods of AnalyzingOutputStream to do whatever you want
于 2015-05-06T02:55:53.617 回答
0

您应该使用记录器,但如果您不想创建您自己的保存 System.out 的 PrintStream。然后调用 System.setOut(yourPrintStream)。

于 2015-05-06T02:19:52.813 回答
0

要在 Java 中捕获来自另一个进程的所有输出,最简单的方法是自己启动该进程Runtime.exec,这将为您提供一个Process具有getOutputStream. 读取该流将为您提供已启动进程的标准输出。

如果您试图捕获任意进程的输出,那么您将面临更大的任务——这可能不是一个好主意。我不知道它在 Windows 上是如何工作的。在 Linux 下,您需要在与要调查的进程相同的用户下运行,或者(更可能)是 root。您可以在 下查看任何给定进程的文件描述符/proc/<process id>/fd/<file descriptor>。stdin、stdout 和 stderr 的文件描述符分别为 0、1 和 2。我建议您在这一点上停下来,重新考虑您要做什么。

于 2015-05-06T03:30:56.400 回答