Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无阻塞地获取进程输出_Java_Git_Stdout - Fatal编程技术网

Java 无阻塞地获取进程输出

Java 无阻塞地获取进程输出,java,git,stdout,Java,Git,Stdout,我想获得一个进程的输出(Git.exe),并将其转换为字符串对象。以前有时候我的代码被阻止了。然后我发现这是因为进程'ErrorStream有一些输出,我必须手动捕获(我对此不感兴趣)。我将代码更改为: public static String runProcess(String executable, String parameter) { try { String path = String.format("%s %s", executable, parameter)

我想获得一个进程的输出(
Git.exe
),并将其转换为字符串对象。以前有时候我的代码被阻止了。然后我发现这是因为进程'
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
中获取输出而不点击块?谢谢。

使用这个和这里描述的
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;
    }
}

使用ProcessBuilder或Apache commons exec


您发布的代码有bug,这是一个很难正确处理的主题。

您应该使用
ProcessBuilder
@fge它会有什么不同吗?你能再解释一下吗?谢谢。它会的:你可以像你想的那样重定向stdout/stderr并运行这个过程,而不用等待stdout/stderr被吞没。我不知道你想做什么,但是如果你想为git创建一个java包装器,我建议你看一看。你能发布一个演示代码吗?另外,请告诉我我的代码中有哪些bug。Thank.outputGobbler.getOutput()将在streamgobbler线程在进程完成之前没有机会读入输入的情况下返回null。