Java调用外部程序的例子
Java调用外部应用程序都是通过“Runtime.getRuntime().exec()”来实现的。但是,因调用的内容不同,而需要额外处理的内容也不同。我就说一下调用BAT和SHELL的情况。
1.如何在Windows下调用BAT。
由于BAT脚本里的命令大部分是windows的内部命令,所以要能正常执行,必须要command.COM(Win95、Win98)或CMD.EXE(XP、NT)的支持。所以我们必须在Runtime.getRuntime().exec()执行的内容前增加“CMD.EXE /C”表示启动一个CMD的终端执行。
2.如何在Linux下调用SHELL。
如果直接在Linux下通过“Runtime.getRuntime().exec()”来执行命令,常常会遇到调用执行的进程无响应,出现这个原因是Linux终端执行的命令处于等待输入状态,所以外部调用的进程无响应。解决的办法就是将系统的标准输入一直打印出来。见下列代码:
// read buffer of parent process' input stream
final BufferedReader reader = new BufferedReader(
new InputStreamReader(System.in));
tIn = new Thread() {
public void run() {
try {
while (true) {
outputStream.write((reader.readLine() + "\n")
.getBytes());
outputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
说完了上述两部分内容,我把完整实现代码贴上来吧。 这里,提供了一个调用方法,及一个用于输出信息和错误的线程类。
public void invoke(ExternalProgramTask task) throws IOException,
InterruptedException {
List<String> cmdArgs = new ArrayList<String>();
final boolean osIsWindows = osIsWindows();
int i = 0;
if (osIsWindows) {
cmdArgs.add(i++, "cmd.exe");
cmdArgs.add(i++, "/C");
} else {
}
for (String str : task.getParameter()) {
cmdArgs.add(i++, str);
}
log(task, Level.INFO, cmdArgs, null);
Process child = Runtime.getRuntime().exec(
cmdArgs.toArray(new String[] {}));
// any output?
Thread tOut = new StreamGobbler(child.getInputStream(),
StreamGobbler.INFO);
// any error message?
Thread tErr = new StreamGobbler(child.getErrorStream(),
StreamGobbler.ERROR);
// any input?
final OutputStream outputStream = child.getOutputStream();
Thread tIn = null;
if (!osIsWindows) {
// read buffer of parent process' input stream
final BufferedReader reader = new BufferedReader(
new InputStreamReader(System.in));
tIn = new Thread() {
public void run() {
try {
while (true) {
outputStream.write((reader.readLine() + "\n")
.getBytes());
outputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
// kick them off
tErr.start();
if (tIn != null)
tIn.start();
tOut.start();
int result = child.waitFor();
outputStream.close();
if (result == 0) {
log(task, Level.INFO, "SUCCESS!", null);
} else {
log(task, Level.SEVERE, "FAILED!", null);
}
}
class StreamGobbler extends Thread {
static final int INFO = 0;
static final int ERROR = 1;
private final InputStream is;
private final int type;
private final OutputStream os;
private volatile boolean isStop = false;
StreamGobbler(InputStream is, int type) {
this(is, type, null);
}
StreamGobbler(InputStream is, int type, OutputStream redirect) {
this.is = is;
this.type = type;
this.os = redirect;
}
public void run() {
try {
PrintWriter pw = null;
if (os != null)
pw = new PrintWriter(os);
InputStreamReader isr = null;
try {
isr = new InputStreamReader(is, System.getProperty(
"sun.jnu.encoding", "UTF8"));
} catch (UnsupportedEncodingException e) {
log(task, Level.SEVERE, e.getLocalizedMessage(), e);
}
if (isr == null) {
log(task, Level.SEVERE,
"InputStreamReader is null,return.", null);
return;
}
BufferedReader br = new BufferedReader(isr);
String line = null;
int lineNumber = 0;
while ((!isStop) && (line = br.readLine()) != null) {
if (pw != null)
pw.println(line);
if (type == INFO) {
System.out.println(" INFO>" + lineNumber + "." + line);
log(task, Level.INFO, lineNumber + "." + line, null);
} else {
System.err.println(" ERROR>" + lineNumber + "." + line);
log(task, Level.SEVERE, lineNumber + "." + line, null);
}
try {
Thread.sleep(10);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
lineNumber++;
}
if (pw != null)
pw.flush();
} catch (IOException ioe) {
ioe.printStackTrace();
log(task, Level.SEVERE, ioe.getLocalizedMessage(), ioe);
}
}
public void stopThread() {
isStop = true;
}
}