转贴请注明出处:http://blog.youkuaiyun.com/froole
用Java执行外部命令非常简单,只要在带入参数的时候注意不要把参数弄错就可以了。
但是,在实际运用中,还有一个比较棘手的问题,就是外部命令执行的timeout。
特别是执行时间比较长的外部命令,如外部的后台处理程序。
当执行这些程序的时候不可能任由他们随便跑,大多数时候,都要事先设定一个外部命令的最大执行时限,也就是timeout,如果超过这个时间程序还没有执行完成,那么将强制杀死程序,并输出错误日志。
JDK的外部执行API没有提供设定timeout的接口,所以,实现此功能,只能自行解决。
在判断执行结果的时候,将会一直对Process的返回值进行判断,前面的部分已经介绍了Process的使用特点,这里将不再重复,只放出代码,如下:
- import java.io.File;
- import java.io.IOException;
- /**
- * 支持timeout的执行外部命令的类定义。<br>
- *
- * @version 1.0
- * @author hao_shunri
- * @see http://blog.youkuaiyun.com/froole
- */
- public class CommandExec {
- /**
- * 用来执行外部命令的{@link Runtime}实现
- */
- private Runtime runtime;
- /**
- * 默认确认timeout的间隔时间,単位:毫秒
- */
- private static final int DEFAULT_TIMEOUT_INTERVAL = 500;
- /**
- * 默认timeout
- */
- private static final long DEFAULT_TIMEOUT = 60 * 1000;
- /**
- * Timout时间,単位:毫秒
- */
- private long timeout = -1;
- /**
- * 确认timeout的间隔时间,単位:毫秒
- */
- private long interval;
- /**
- *
- * @param runtime 用来执行外部命令的{@link Runtime}实现
- * @param timeout timeout时间
- * @param invterval 换算timeout的间隔时间
- */
- public CommandExec(Runtime runtime, long timeout, long invterval){
- this.timeout = timeout;
- this.interval = invterval;
- this.runtime = runtime;
- }
- /**
- *
- *
- * @param timeout timeout时间
- * @param invterval 换算timeout的间隔时间
- */
- public CommandExec(long timeout, long invterval){
- this(Runtime.getRuntime(), timeout, invterval);
- }
- /**
- *
- *
- * @param timeout timeout时间
- */
- public CommandExec(long timeout){
- this(timeout, DEFAULT_TIMEOUT_INTERVAL);
- }
- /**
- *
- *
- */
- public CommandExec(){
- this(DEFAULT_TIMEOUT, DEFAULT_TIMEOUT_INTERVAL);
- }
- /**
- *
- * 执行外部命令
- *
- * @param commands
- * 命令数组
- * @return
- * @throws IOException
- */
- public Process exec(String[] commands) throws IOException, InterruptedException {
- return exec(commands, null);
- }
- /**
- * 执行外部命令
- *
- * @param commands
- * 命令数组
- * @param dir
- * 临时目录
- * @return
- * @throws IOException
- */
- public Process exec(String[] commands, File dir) throws IOException, InterruptedException {
- return exec(commands, null, dir);
- }
- /**
- *
- * 执行外部命令
- *
- * @param commands
- * 命令数组
- * @param envp
- * 环境变量
- * @param dir
- * 临时目录
- * @return
- * @throws IOException
- * @throws IllegalThreadStateException
- */
- public Process exec(String[] commands, String[] envp, File dir) throws IOException, InterruptedException {
- if (commands == null) {
- throw new NullPointerException();
- }
- Process process = runtime.exec(commands, envp, dir);
- // 设定timeout
- long limitTime = timeout + System.currentTimeMillis();
- // 状态
- Integer status = null;
- do {
- try {
- status = process.exitValue();
- break;
- } catch (IllegalThreadStateException e) {
- try {
- Thread.sleep(getInterval());
- } catch (InterruptedException we) {
- return null;
- }
- }
- } while (System.currentTimeMillis() < limitTime);
- if (status == null) {
- process.destroy();
- try {
- status = process.waitFor();
- } catch (InterruptedException e) {
- throw e;
- }
- }
- return process;
- }
- /**
- * 设定Timout时间,単位:毫秒
- *
- * @param timeout
- * Timout时间,単位:毫秒
- */
- public void setTimeout(long timeout) {
- this.timeout = timeout;
- }
- /**
- * 提取Timout时间,単位:毫秒
- *
- * @return Timout时间,単位:毫秒
- */
- public long getTimeout() {
- return timeout;
- }
- /**
- * 提取确认timeout的间隔时间,単位:毫秒
- *
- * @return 确认timeout的间隔时间,単位:毫秒
- */
- public long getInterval() {
- return interval;
- }
- /**
- * 设定确认timeout的间隔时间,単位:毫秒
- *
- * @param interval
- * 确认timeout的间隔时间,単位:毫秒
- */
- public void setInterval(long interval) {
- this.interval = interval;
- }
- }
待续
相关:
-浅析Java执行外部命令的几个要点(1)
-浅析Java执行外部命令的几个要点(2)
-浅析Java执行外部命令的几个要点(3)
-浅析Java执行外部命令的几个要点(4)
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type="text/javascript"></script>
转贴请注明出处:http://blog.youkuaiyun.com/froole