无阻塞地获取流程输出

时间:2013-01-21 15:16:16

标签: java git stdout

我希望得到一个进程'输出(确切地说Git.exe)并将其转换为String对象。以前有时我的代码被阻止了。然后我发现这是因为进程'ErrorStream有一些输出,我必须手动捕获它(我不感兴趣)。我把我的代码更改为:

public static String runProcess(String executable, String parameter) {
    try {
        String path = String.format("%s %s", executable, parameter);
        Process pr = Runtime.getRuntime().exec(path);

        // ignore errors
        StringWriter errors = new StringWriter();
        IOUtils.copy(pr.getErrorStream(), errors);

        StringWriter writer = new StringWriter();
        IOUtils.copy(pr.getInputStream(), writer);

        pr.waitFor();
        return writer.toString();
    } catch (Exception e) {
        return null;
    }
}

现在它工作得很好,但是又一次,有时它会在这一行再次被阻止: IOUtils.copy(pr.getErrorStream(), errors);

有没有什么办法可以让我git.exe的输出没有碰到一个块?感谢。

2 个答案:

答案 0 :(得分:1)

使用ProcessBuilder或Apache commons-exec。

您发布的代码存在错误,这是一个难以理解的主题。

答案 1 :(得分:0)

使用此beautiful article和那里描述的StreamGobbler类(我稍微修改了一下),我解决了这个问题。我对StreamGobbler

的实施
class StreamGobbler extends Thread {
    InputStream is;
    String output;

    StreamGobbler(InputStream is) {
        this.is = is;
    }

    public String getOutput() {
        return output;
    }

    public void run() {
        try {
            StringWriter writer = new StringWriter();
            IOUtils.copy(is, writer);
            output = writer.toString();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

我的功能是:

public static String runProcess(String executable, String parameter) {
    try {
        String path = String.format("%s %s", executable, parameter);
        Process pr = Runtime.getRuntime().exec(path);

        StreamGobbler errorGobbler = new StreamGobbler(pr.getErrorStream());
        StreamGobbler outputGobbler = new StreamGobbler(pr.getInputStream());

        // kick them off concurrently
        errorGobbler.start();
        outputGobbler.start();

        pr.waitFor();
        return outputGobbler.getOutput();
    } catch (Exception e) {
        return null;
    }
}