在我的Java应用程序中,我需要执行一些脚本作为子进程并监视来自Java的stdout上的输出,以便我可以在必要时对某些输出做出反应。
我正在使用apache commons-exec来生成子进程并将已执行脚本的stdout重定向到输入流。
我遇到的问题是,从流中读取时,Java进程被阻塞,直到子进程完成执行。我不能等到子进程结束才能对输出作出反应,但我需要在它可用时异步读取它。
以下是我的Java代码:
public class SubProcessReact {
public static class LogOutputStreamImpl extends LogOutputStream {
@Override
protected void processLine(String line, int logLevel) {
System.out.println("R: " + line);
}
}
public static void main (String[] args) throws IOException, InterruptedException {
CommandLine cl = CommandLine.parse("python printNumbers.py");
DefaultExecutor e = new DefaultExecutor();
ExecuteStreamHandler sh = new PumpStreamHandler(new LogOutputStreamImpl());
e.setStreamHandler(sh);
Thread th = new Thread(() -> {
try {
e.execute(cl);
} catch (IOException e1) {
e1.printStackTrace();
}
});
th.start();
}
}
对于这个例子,子进程是一个python脚本,它在输出之间有一秒钟的延迟向上计数,这样我就可以在数据进入时验证Java代码是否正在响应。
Python代码:
import time
for x in range(0,10):
print x
time.sleep(1)
我希望LogOutputStreamImpl可以打印每一行,但实际发生的是它读取流块直到子流程完成,然后打印所有输出。
我有什么办法可以按照我的意愿来完成这项工作吗?