之前一个项目用到了java调用命令行程序。
其实jdk已经把调用的方法封装的很好了。但毕竟是沙箱之外的程序,资源的清理工作不做好,系统很快就会崩溃。还是有很多细节处需要小心处理
java.lang.Process抽象类封装一个本机进程。
Process process = Runtime.getRuntime().exec(commandStr);
将调用本机命令commandStr
这本机命令就是在DOS环境下可以执行的各种命令。
如果想要查看该本地命令执行时的输出,可以直接获取到Process的InputStream
void display (Process process) throws IOException{
String s;
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
while ((s = bufferedReader.readLine()) != null)
logger.debug(s);
}
之后,可以调用Process的waitFor方法等待程序运行完成。但是这个方法是无参的,也就是不能设置超时!!这个很让人郁闷。万一调用的程序不稳定,或者进入了死循环,不设置超时系统就会在这里假死了。将这个Process封装进一个Runnable,另起一个线程执行,并在调用线程中并设置等待超时
Thread thread = new Thread (new ProcessThread(process, type));
thread.start();
thread.join(TIMEOUT);
thread.interrupt();
并在 ProcessThread 类中,做好 InterruptedException 的异常处理——资源清理。
资源清理主要是杀死没有正确结束的进程。通过进程名字或者PID都可以直接杀死。Windows下关闭进程的方法有几种,可以在网上搜搜。我这次使用了taskkill命令。例如关闭一个Excel进程,命令格式为 taskkill /IM EXCEL.EXE /F /T 同样将这个命令用一次Process调用执行即可。
当然,也可以直接设置一个finally快调用process的destroy方法强制杀死之。但是也得要在超时处理中完成。
最后记一笔,在DOS CMD命令中,如何查看上一个程序运行的返回值,在DOS里成为错误码。直接运行
echo %errorlevel%
即可查看上一条命令的返回值(错误码)。