一、 用法:
public Process exec(String command)-----在單獨的進程中執(zhí)行指定的字符串命令。
public Process exec(String [] cmdArray)---在單獨的進程中執(zhí)行指定命令和變量
public Process exec(String command, String [] envp)----在指定環(huán)境的獨立進程中執(zhí)行指定命令和變量
public Process exec(String [] cmdArray, String [] envp)----在指定環(huán)境的獨立進程中執(zhí)行指定的命令和變量
public Process exec(String command,String[] envp,File dir)----在有指定環(huán)境和工作目錄的獨立進程中執(zhí)行指定的字符串命令
public Process exec(String[] cmdarray,String[] envp,File dir)----在指定環(huán)境和工作目錄的獨立進程中執(zhí)行指定的命令和變量
二、cmd命令執(zhí)行窗口開閉指令
cmd /c dir 是執(zhí)行完dir命令后關(guān)閉命令窗口。
cmd /k dir 是執(zhí)行完dir命令后不關(guān)閉命令窗口。
cmd /c start dir 會打開一個新窗口后執(zhí)行dir指令,原窗口會關(guān)閉。
cmd /k start dir 會打開一個新窗口后執(zhí)行dir指令,原窗口不會關(guān)閉。
三、經(jīng)驗總結(jié)
Runtime run = Runtime.getRuntime();
Process p = run.exec("ping 127.0.0.1");
這是基本用法,通過p可以獲得命令執(zhí)行過程中的輸入流和錯誤流(也就是打印信息)
InputStream ins= p.getInputStream();
InputStream ers= p.getErrorStream();
這兩個流要用不同的線程去處理,不然容易引發(fā)阻塞
當默認的路徑(java代碼執(zhí)行默認為class路徑)執(zhí)行bat命令時,如果沒有跨盤符,通過bat文件的絕對路徑或者相對路徑可以執(zhí)行到對應(yīng)的bat命令,如果跨盤符,就必須設(shè)置執(zhí)行文件路徑了,即需要用到如下命令 public Process exec(String command,String[] envp,File dir),例如:Process p = run.exec("ceshi.bat",null,new File("d:\ceshi\"));或者Process p = run.exec(new String[]{"cmd","/c","start","ceshi.bat"},null,new File("d:\ceshi\"));
如果命令執(zhí)行時報“java.io.IOException: Cannot run program "****": CreateProcess error=2, ?????μ???”這樣的錯誤,表明命令語法錯誤,即命令不能被正確識別,這個需要仔細檢查命令語法,尤其是要注意有空格的長命令,列如run.exec("%comspec% /c \ceshi\ceshi.bat");此命令需要run.exec(new String[]{"cmd","/c","%comspec% /c \ceshi\ceshi.bat"},null,null);
如果執(zhí)行時報“java.lang.IllegalArgumentException: Executable name has embedded quote,split the arguments”的異常,很可能是命令中有空格識別異常,可以試著把空格轉(zhuǎn)成帶引號的空格,列如run.exec("c:\ceshi file\ceshi.bat".replace(" ","" ""))
如果發(fā)現(xiàn)一個bat命令在CMD窗口中可以正常執(zhí)行,但通過java的Runtime執(zhí)行就會阻塞,八成可能是命令執(zhí)行中開了新窗口,但老窗口沒關(guān)導(dǎo)致的,列如run.exec(new String[]{"cmd","/k","ceshi.bat"},null,new File("d:\ceshi\"));這條語句在執(zhí)行的過程中因為存在“/k”的存在,導(dǎo)致命令執(zhí)行完dir命令后不關(guān)閉命令窗口,在獲取流的時候,流一直不關(guān)閉,就會形成阻塞,只要把“/k”換成“/c”就行了
如果遇到需要執(zhí)行兩個bat文件命令bat1、bat2,其中bat2依賴與bat1的環(huán)境,即在CMD窗口中,先執(zhí)行bat1后再在同一個窗口中執(zhí)行bat2,就很正常,但如果在兩個不同的CMD窗口執(zhí)行這兩個命令,就只有bat1執(zhí)行成功,這個解決辦法很簡單,只要新建一個bat文件,然后通過“call”命令來調(diào)用這兩個bat文件,就不會出錯了(這有個知識點:start調(diào)用一個bat命令會新啟一個CMD窗口,call不會新開窗口,而是在當前窗口執(zhí)行調(diào)用的bat文件命令,執(zhí)行完后,繼續(xù)執(zhí)行下面的命令,所以start雷士java中的多線程啟動,call類似java中簡單的函數(shù)調(diào)用)
四、示例代碼:
public class RuntimeTest {
public static void main(String[] args) {
RuntimeTest s = new RuntimeTest();
s.test();
}
public void test(){
Runtime run =Runtime.getRuntime();
try {
Process p = run.exec("ping 127.0.0.1");
InputStream ins= p.getInputStream();
InputStream ers= p.getErrorStream();
new Thread(new inputStreamThread(ins)).start();
p.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
class inputStreamThread implements Runnable{
private InputStream ins = null;
private BufferedReader bfr = null;
public inputStreamThread(InputStream ins){
this.ins = ins;
this.bfr = new BufferedReader(new InputStreamReader(ins));
}
@Override
public void run() {
String line = null;
byte[] b = new byte[100];
int num = 0;
try {
while((num=ins.read(b))!=-1){
System.out.println(new String(b,"gb2312"));
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}