从Java启动进程时,如果我不从管道中读取内容,stderr和stdout都可能在输出上阻塞。目前,我有一个主动从另一个线程读取主线程块的线程。

是否有一种简单的方法来连接两个流,否则会导致子进程继续运行而又不会丢失stderr中的数据?

最佳答案

在ProcessBuilder上设置redirectErrorStream属性,以将stderr输出发送到stdout:

ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);

然后,您应该创建一个线程来处理流程流,如下所示:
Process p = builder.start();

InputHandler outHandler = new InputHandler(p.getInputStream());

其中InputHandler定义为:
private static class InputHandler extends Thread {

    private final InputStream is;

    private final ByteArrayOutputStream os;

    public InputHandler(InputStream input) {
        this.is = input;
        this.os = new ByteArrayOutputStream();
    }

    public void run() {
        try {
            int c;
            while ((c = is.read()) != -1) {
                os.write(c);
            }
        } catch (Throwable t) {
            throw new IllegalStateException(t);
        }
    }

    public String getOutput() {
        try {
        os.flush();
        } catch (Throwable t) {
            throw new IllegalStateException(t);
        }
        return os.toString();
    }

}

另外,只需为InputStream和ErrorStream创建两个InputHandlers。知道如果您不阅读它们,该程序将被阻止,这是90%的努力:)

10-06 02:48