FROM:http://segmentfault.com/blog/lidonghao/1190000000372535
在前一篇博文中,简单介绍了如何使用Process类来调用命令行的功能,那样使用Process会有一个很大的问题,就是可能会出现无限阻塞的情况,永远都无法返回结果。以下是Process的API说明,注意加粗的部分。
ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例,该实例可用来控制进程并获得相关信息。Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。
创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft Windows 上的 Win16/DOS 进程,或者 shell 脚本。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin、stdout 和 stderr)操作都将通过三个流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。
解决进程无限阻塞的方法是在执行命令时,设置一个超时时间,下面提供一个工具类,对Process使用进行包装,向外提供设置超时的接口。
- ExecuteResult类,对执行命令的结果进行封装,可以从中获取退出码和输出内容。
-
View Code
1 public class ExecuteResult { 2 @Override 3 public String toString() { 4 return "ExecuteResult [exitCode=" + exitCode + ", executeOut=" 5 + executeOut + "]"; 6 } 7 8 private int exitCode; 9 private String executeOut; 10 11 public ExecuteResult(int exitCode, String executeOut) { 12 super(); 13 this.exitCode = exitCode; 14 this.executeOut = executeOut; 15 } 16 17 public int getExitCode() { 18 return exitCode; 19 } 20 21 public void setExitCode(int exitCode) { 22 this.exitCode = exitCode; 23 } 24 25 public String getExecuteOut() { 26 return executeOut; 27 } 28 29 public void setExecuteOut(String executeOut) { 30 this.executeOut = executeOut; 31 } 32 33 }