在Java中执行脚本命令以及调用外部程序说明
一、Java中关于ProcessBuilder 和 Runtime 类的介绍
在Java中要想执行脚本或者调用程序必须通过ProcessBuilder 和 Runtime 类,以上两个类任选一个就行,关于他们的介绍如下:
ProcessBuilder.start() 和 Runtime.exec() 方法都被用来创建一个操作系统进程(执行命令行操作),并返回
Process 子类的一个实例,该实例可用来控制进程状态并获得相关信息。
Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。创建进程的方法可能无法针对某些本机平台上的特定进程很好地工作,比如,本机窗口进程,守护进程,Microsoft
Windows 上的 Win16/DOS 进程,或者 shell 脚本。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin、stdout 和 stderr)操作都将通过三个流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。因为有些本机平台仅针对标准输入和输出流提供有限的缓冲区大小,如果读写子
进程的输出流或输入流迅速出现失败,则可能导致子进程阻塞,甚至产生死锁。 当没有 Process 对象的更多引用时,不是删掉子进程,而是继续异步执行子进程。 对于带有 Process 对象的 Java 进程,没有必要异步或并发执行由 Process 对象表示的进程。
每个ProcessBuilder实例管理一个进程属性集。ProcessBuilder的start()方法利用这些属性创建一个新的Process实例。start()方法可以从同一实例重复调用,以利用相同或者相关的属性创建新的子进程。
不同点:
ProcessBuilder.start() 和 Runtime.exec()传递的参数有所不同,Runtime.exec()可接受一个单独的字符串,这个字符串是通过空格来分隔可执行命令程序和参数的;也可以接受字符串数组参数。而ProcessBuilder的构造函数是一个字符串列表或者数组。列表中第一个参数是可执行命令程序,其他的是命令行执行是需要的参数。
通过查看JDK源码可知,Runtime.exec最终是通过调用ProcessBuilder来真正执行操作的。
二、Runtime演示示例
1.在windows下调用dos命令:
下面演示了在windows下执行dos命令"chdir",并将执行结果输出的示例。
public class TestDos { /** * 在windows下执行dos命令并在console端输出 * * @throws Exception */ public static void main(String[] args) throws Exception { String strCmd = "chdir";//待执行的dos命令(chdir命令作用是列出当前的工作目录) Process process = Runtime.getRuntime().exec("cmd /k " + strCmd);//通过cmd程序执行cmd命令 //process.waitFor(); //读取屏幕输出 BufferedReader strCon = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = strCon.readLine()) != null) { System.out.println(line); } } }
eclipsed console输出结果如下:
public class TestDos { /** * 在windows下调用dos命令 * * @throws Exception */ public static void main(String[] args) throws Exception { String strCmd = "dos命令";//待执行的dos命令 Runtime.getRuntime().exec("cmd /c " + strCmd).waitFor();//通过cmd程序执行dos命令 } }
注:执行dos命令时,需在命令前加上"cmd /x"参数,其中x可以为c或者k值,具体说明如下:
cmd /c chdir 是执行完dir命令后关闭命令窗口。
cmd /k chdir 是执行完dir命令后不关闭命令窗口。
cmd /c start chdir 会打开一个新窗口后执行dir指令,原窗口会关闭。
cmd /k start chdir 会打开一个新窗口后执行dir指令,原窗口不会关闭。
2.在windows下调用外部程序:
下面演示了调用QQ程序的过程:
/** * 在windows下调用QQ程序示例 * */ public class CallQQ { /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { Runtime.getRuntime().exec("D:\\Program Files (x86)\\Tencent\\QQ\\QQProtect\\Bin\\QQProtect.exe"); } }
3.在Linux下执行shell命令:
下面演示了在Linux中执行shell命令pwd,并显示执行结果:
/** * 执行Linux的shell命令并在console端输出结果 * */ public class CallShell { /** * @throws Exception */ public static void main(String[] args) throws Exception { String strCmd = "pwd";//执行shell命令 Process process = Runtime.getRuntime().exec(strCmd);//通过执行cmd命令调用protoc.exe程序 BufferedReader strCon = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = strCon.readLine()) != null) { System.out.println("java print:"+line); } } }console端输出结果如下:
如果不需要console端输出可以简写如下:
/** * 执行Linux的shell命令 * */ public class CallShell { /** * @throws Exception */ public static void main(String[] args) throws Exception { String strCmd = "shell命令";//待执行shell命令 Runtime.getRuntime().exec(strCmd).waitFor();//通过执行cmd命令调用protoc.exe程序 } }
4.在Linux下调用shell脚本并输出结果:
/** * 在linux下调用shell脚本并在console端输出脚本的执行结果 * */ public class CallShell { /** * @throws Exception */ public static void main(String[] args) throws Exception { String strCmd = "/home/zhu/test/test.sh";//待调用shell脚本 Process process = Runtime.getRuntime().exec(strCmd);//通过执行cmd命令调用protoc.exe程序 BufferedReader strCon = new BufferedReader(new InputStreamReader(process.getInputStream())); String line; while ((line = strCon.readLine()) != null) { System.out.println("java print:"+line); } } }三、ProcessBuilder使用示例
ProcessBuilder的使用参考如下:
String[] as = new String[]{“待执行命令1”,"待执行命令2",.........};
ProcessBuilder pb = new ProcessBuilder(as);
pb.start();
使用ProcessBuilder可以依次执行多个命令