3

プロセスの出力 (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ブロックをヒットせずにから出力を取得する方法はありますか? ありがとう。

4

2 に答える 2

3

この美しい記事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;
    }
}
于 2013-01-21T16:03:54.397 に答える
1

ProcessBuilder または Apache commons-exec を使用します。

投稿されたコードにはバグがあります。これは正しく理解するのが難しいトピックです。

于 2013-01-21T16:16:56.787 に答える