. 작은 클래스 하나. JVM 리소스 누출을 수정하는 JavaWorld streamgobbler 클래스가 있습니다. JVM6 및 JVM7에 대해서는 여전히 유효한 지 모르지만 다치게하지는 않습니다. 도우미는 나중에 사용할 수 있도록 출력 버퍼를 읽을 수 있습니다.
import java.io.*;
/**
* Execute external process and optionally read output buffer.
*/
public class ShellExec {
private int exitCode;
private boolean readOutput, readError;
private StreamGobbler errorGobbler, outputGobbler;
public ShellExec() {
this(false, false);
}
public ShellExec(boolean readOutput, boolean readError) {
this.readOutput = readOutput;
this.readError = readError;
}
/**
* Execute a command.
* @param command command ("c:/some/folder/script.bat" or "some/folder/script.sh")
* @param workdir working directory or NULL to use command folder
* @param wait wait for process to end
* @param args 0..n command line arguments
* @return process exit code
*/
public int execute(String command, String workdir, boolean wait, String...args) throws IOException {
String[] cmdArr;
if (args != null && args.length > 0) {
cmdArr = new String[1+args.length];
cmdArr[0] = command;
System.arraycopy(args, 0, cmdArr, 1, args.length);
} else {
cmdArr = new String[] { command };
}
ProcessBuilder pb = new ProcessBuilder(cmdArr);
File workingDir = (workdir==null ? new File(command).getParentFile() : new File(workdir));
pb.directory(workingDir);
Process process = pb.start();
// Consume streams, older jvm's had a memory leak if streams were not read,
// some other jvm+OS combinations may block unless streams are consumed.
errorGobbler = new StreamGobbler(process.getErrorStream(), readError);
outputGobbler = new StreamGobbler(process.getInputStream(), readOutput);
errorGobbler.start();
outputGobbler.start();
exitCode = 0;
if (wait) {
try {
process.waitFor();
exitCode = process.exitValue();
} catch (InterruptedException ex) { }
}
return exitCode;
}
public int getExitCode() {
return exitCode;
}
public boolean isOutputCompleted() {
return (outputGobbler != null ? outputGobbler.isCompleted() : false);
}
public boolean isErrorCompleted() {
return (errorGobbler != null ? errorGobbler.isCompleted() : false);
}
public String getOutput() {
return (outputGobbler != null ? outputGobbler.getOutput() : null);
}
public String getError() {
return (errorGobbler != null ? errorGobbler.getOutput() : null);
}
//********************************************
//********************************************
/**
* StreamGobbler reads inputstream to "gobble" it.
* This is used by Executor class when running
* a commandline applications. Gobblers must read/purge
* INSTR and ERRSTR process streams.
* http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4
*/
private class StreamGobbler extends Thread {
private InputStream is;
private StringBuilder output;
private volatile boolean completed; // mark volatile to guarantee a thread safety
public StreamGobbler(InputStream is, boolean readStream) {
this.is = is;
this.output = (readStream ? new StringBuilder(256) : null);
}
public void run() {
completed = false;
try {
String NL = System.getProperty("line.separator", "\r\n");
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
if (output != null)
output.append(line + NL);
}
} catch (IOException ex) {
// ex.printStackTrace();
}
completed = true;
}
/**
* Get inputstream buffer or null if stream
* was not consumed.
* @return
*/
public String getOutput() {
return (output != null ? output.toString() : null);
}
/**
* Is input stream completed.
* @return
*/
public boolean isCompleted() {
return completed;
}
}
}
다음은 .vbs 스크립트에서 출력을 읽는 예제이지만 Linux sh 스크립트에서도 비슷하게 작동합니다.
Process p = Runtime.getRuntime().exec("script");
p.waitFor();
String output = IOUtils.toString(p.getInputStream());
String errorOutput = IOUtils.toString(p.getErrorStream());
경고 : : 많은 출력을 생성하지 않는 프로세스에 대한
ShellExec exec = new ShellExec(true, false);
exec.execute("cscript.exe", null, true,
"//Nologo",
"//B", // batch mode, no prompts
"//T:320", // timeout seconds
"c:/my/script/test1.vbs", // unix path delim works for script.exe
"script arg 1",
"script arg 2",
);
System.out.println(exec.getOutput());
[기사] (http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html)을보십시오. – kgiannakakis