在子进程可用时读取stdout流

时间:2015-12-20 15:34:50

标签: java stream subprocess apache-commons-exec

在我的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可以打印每一行,但实际发生的是它读取流块直到子流程完成,然后打印所有输出。

我有什么办法可以按照我的意愿来完成这项工作吗?

0 个答案:

没有答案