阅读 System.Out
Reading System.Out
所以,我想做的基本上是过滤通过 System.out
和 System.err
的所有内容,是否可以应用某种过滤器或创建我自己的 OutputStream
用System.out
导流,然后正常处理?
为清楚起见编辑:
为了澄清,我需要从其他程序中读取 System.out 的内容,并按照我认为合适的方式对其进行操作,因此记录器并不是一个真正的选择,因为我无法控制其他程序将使用的内容。
为更清晰起见进行编辑:
我正在为一个更大的程序创建一个插件,该程序需要从其他插件读取写入 System.out 的所有内容。因为它是一个基于插件的系统,所以我的插件 运行 开启的进程将始终与其他插件 运行 开启的进程相同。
你应该使用记录器,但如果你不想,你可以创建自己的 PrintStream 来保存 System.out。然后调用 System.setOut(yourPrintStream).
有一点我不太清楚:你提到你想要 "read what goes out of System.out from other programs"。您的应用程序是在创建流程并希望监控其标准 out/err,还是您希望监控流程本身的标准 out/err?
对于前一种情况,创建进程后,您可以获得它的output, input and error流。
对于后一种情况,您可以将 Java 过程中的标准替换为 System.setOut(yourOwnOutputStream);
但是,如果您正在尝试处理完全不相关的流程流,我相信如果调用者不通过管道将 stdout/stderr 传递给您的流程(除非通过某些特定于平台的方法),就无法做到这一点
更新:
为了"intercept"标准出来的,跟那些经典"filter outputstreams"无异。你可以做的是这样的:
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
要捕获 Java 中另一个进程的所有输出,最简单的方法是使用 Runtime.exec
自己启动进程,这将为您提供一个 Process
对象,该对象具有 getOutputStream
.读取该流将为您提供已启动进程的标准输出。
如果您正在尝试捕获任意进程的输出,您将面临更大的任务 - 这可能不是一个好主意。我不知道它在 Windows 上是如何工作的。在 Linux 下,您需要 运行 与您要调查的进程或(更有可能)root 处于同一用户下。您可以在 /proc/<process id>/fd/<file descriptor>
下查看任何给定进程的文件描述符。 stdin、stdout 和 stderr 的文件描述符分别为 0、1 和 2。我会建议你在这一点上停下来,重新考虑你要做什么。
所以,我想做的基本上是过滤通过 System.out
和 System.err
的所有内容,是否可以应用某种过滤器或创建我自己的 OutputStream
用System.out
导流,然后正常处理?
为清楚起见编辑: 为了澄清,我需要从其他程序中读取 System.out 的内容,并按照我认为合适的方式对其进行操作,因此记录器并不是一个真正的选择,因为我无法控制其他程序将使用的内容。
为更清晰起见进行编辑: 我正在为一个更大的程序创建一个插件,该程序需要从其他插件读取写入 System.out 的所有内容。因为它是一个基于插件的系统,所以我的插件 运行 开启的进程将始终与其他插件 运行 开启的进程相同。
你应该使用记录器,但如果你不想,你可以创建自己的 PrintStream 来保存 System.out。然后调用 System.setOut(yourPrintStream).
有一点我不太清楚:你提到你想要 "read what goes out of System.out from other programs"。您的应用程序是在创建流程并希望监控其标准 out/err,还是您希望监控流程本身的标准 out/err?
对于前一种情况,创建进程后,您可以获得它的output, input and error流。
对于后一种情况,您可以将 Java 过程中的标准替换为 System.setOut(yourOwnOutputStream);
但是,如果您正在尝试处理完全不相关的流程流,我相信如果调用者不通过管道将 stdout/stderr 传递给您的流程(除非通过某些特定于平台的方法),就无法做到这一点
更新:
为了"intercept"标准出来的,跟那些经典"filter outputstreams"无异。你可以做的是这样的:
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
要捕获 Java 中另一个进程的所有输出,最简单的方法是使用 Runtime.exec
自己启动进程,这将为您提供一个 Process
对象,该对象具有 getOutputStream
.读取该流将为您提供已启动进程的标准输出。
如果您正在尝试捕获任意进程的输出,您将面临更大的任务 - 这可能不是一个好主意。我不知道它在 Windows 上是如何工作的。在 Linux 下,您需要 运行 与您要调查的进程或(更有可能)root 处于同一用户下。您可以在 /proc/<process id>/fd/<file descriptor>
下查看任何给定进程的文件描述符。 stdin、stdout 和 stderr 的文件描述符分别为 0、1 和 2。我会建议你在这一点上停下来,重新考虑你要做什么。