通過Java執(zhí)行系統(tǒng)命令,與cmd中或者終端上一樣執(zhí)行shell命令,最典型的用法就是使用Runtime.getRuntime().exec(command)或者new ProcessBuilder(cmdArray).start()。從JDK1.5開始,官方提供并推薦使用ProcessBuilder類進(jìn)行shell命令操作。所以此處主要是對(duì)ProcessBuilder進(jìn)行介紹。

如圖1的代碼片段所示,使用ProcessBuilder很簡單,只需要通過Arrays.asList()構(gòu)建一個(gè)List的參數(shù)集合,然后在ProcessBuilder的構(gòu)造函數(shù)傳入?yún)?shù),即可 start()方法執(zhí)行;圖中第一個(gè)參數(shù) 值? Python用來指定該命令是一條Python命令,后面的參數(shù)值對(duì)應(yīng)調(diào)用函數(shù)的參數(shù),同時(shí)可以使用processBuilder.directory()來指定程序的工作目錄,這是很有必要的。
相對(duì)來說,調(diào)用Windows系統(tǒng)的客戶端程序,就要相對(duì)簡單得多,我們不需要額外的指定,該命令是什么樣的類型命令。如下圖2所示:

當(dāng)然,除了使用Arrays.asList()來構(gòu)建參數(shù)集合,ProcessBuilder也提供了可變參數(shù)的方式進(jìn)行對(duì)調(diào)用函數(shù)的參數(shù)進(jìn)行賦值:public ProcessBuilder(String... command);
Process??p =new?ProcessBuilder("ipconfig","/all").start();?//執(zhí)行ipconfig/all命令
接下來,說說返回值和錯(cuò)誤信息的接收的問題。ProcessBuilder.start()后會(huì)返回一個(gè)Process的進(jìn)程對(duì)象,通過這個(gè)對(duì)象可以獲取到 Inputstream,讀取流中的數(shù)據(jù)即可獲取到相應(yīng)的信息。

圖3所示,通過一行一行的讀取流的方式獲取到進(jìn)程中的輸出信息和錯(cuò)誤信息,但是在實(shí)際當(dāng)中這種方式是不可取的,原因是:首先,這種一行一行的讀取,當(dāng)進(jìn)程不能即時(shí)的返回?cái)?shù)據(jù),那么readLine()將讀取不到數(shù)據(jù),并在程序未執(zhí)行完成前結(jié)束進(jìn)程的繼續(xù)往下執(zhí)行,程序退出;其次,當(dāng)執(zhí)行的程序輸出信息過多時(shí),InputStream流會(huì)造成進(jìn)程阻塞;所以不建議使用以上方式去獲取輸出信息,推薦使用 緩存池的方式進(jìn)行獲取。

通過介紹,是不是對(duì)ProcessBuilder有了一個(gè)大概的了解了呢?