问题
I want to get a process' output (Git.exe to be exact) and convert it to a String object. Previously sometimes my code was blocked. Then I figured out that it's because the process' ErrorStream has some output and I have to manually capture that (which I'm not interested in). I changed my code to this:
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;
}
}
Now it works mostly fine, but then again, sometimes it gets blocked again in this line:
IOUtils.copy(pr.getErrorStream(), errors);.
Is there some way I could just get the output from the git.exe without hitting a block? Thanks.
回答1:
Use ProcessBuilder or Apache commons-exec.
Your posted code has bugs, this is a hard topic to get right.
回答2:
Using this beautiful article and the StreamGobbler class described there (which I modified a little) I solved the problem. My implementation of 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();
}
}
}
and my function is:
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;
}
}
来源:https://stackoverflow.com/questions/14441652/get-process-output-without-blocking