最近项目需要用java解析3dsmax场景文件,但是3dsmax没有提供java版的api,只能通过max SDK(C++)或者maxScript来解析,为此用maxScript写了个ms文件,然后通过java来调用执行,为了获取执行后的结果,所以使用如下代码:
process = Runtime.getRuntime().exec(cmdStr);
if(process.waitFor() == 0){
...
}
但是调用后,一致没有反馈,而且通过进程管理器可以发现3dsmax进程,但是没有启动完全,当内存到达某个值的时候就不再变化,开始还以为是jvm设置问题,百度下才发现时process.waitFor的问题。
waitFor() 表示当前 Process 所在的子线程处于等待状态,如有必要,一直要等到由该 Process 对象表示的进程已经终止,网上说如果我们在调用此方法时,如果不注意的话,很容易出现主线程阻塞, Process 也挂起的情况。这就是我遇到的问题,网上的解决办法是,在调用 waitFor() 的时候, Process 需要向主线程汇报运行状况,所以要注意清空缓存区,即 InputStream 和 ErrorStream ,注意这里 InputStream 和 ErrorStream 都需要清空。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class ProcessStreamClean extends Thread {
private InputStream inputStream;
private String type;
public ProcessStreamClean(InputStream inputStream, String type) {
this.inputStream = inputStream;
this.type = type;
}
public void run() {
try {
InputStreamReader inputStreamReader = new InputStreamReader(
inputStream);
BufferedReader br = new BufferedReader(inputStreamReader);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(type + ">" + line);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
接下来通过函数来调用
public class ProcessTest {
public static void main(String[] args) {
Process process = null;
try {
String cmd = "\"F:/develop/Autodesk/3ds Max 2013/3dsmax.exe\""
process = Runtime.getRuntime().exec(cmd);
new ProcessStreamClean(process.getInputStream(), "INFO").start();
new ProcessStreamClean(process.getErrorStream(), "ERROR").start();
int status = process.waitFor();
System.out.println("Process exitValue: " + status);
} catch (Exception e) {
System.out.println("执行" + cmd + "出现错误," + e.toString());
} finally {
if (process == null) {
process.destroy();
}
process = null;
}
}
}