深入研究java.lang.Process類
**一仿荆、概述
** Process類是一個(gè)抽象類(所有的方法均是抽象的)妻怎,封裝了一個(gè)進(jìn)程(即一個(gè)執(zhí)行程序)箫锤。 Process 類提供了執(zhí)行從進(jìn)程輸入、執(zhí)行輸出到進(jìn)程僚焦、等待進(jìn)程完成锰提、檢查進(jìn)程的退出狀態(tài)以及銷毀(殺掉)進(jìn)程的方法。 ProcessBuilder.start() 和 Runtime.exec 方法創(chuàng)建一個(gè)本機(jī)進(jìn)程,并返回 Process 子類的一個(gè)實(shí)例立肘,該實(shí)例可用來控制進(jìn)程并獲取相關(guān)信息边坤。
創(chuàng)建進(jìn)程的方法可能無法針對(duì)某些本機(jī)平臺(tái)上的特定進(jìn)程很好地工作,比如谅年,本機(jī)窗口進(jìn)程茧痒,守護(hù)進(jìn)程,Microsoft Windows 上的 Win16/DOS 進(jìn)程融蹂,或者 shell 腳本旺订。創(chuàng)建的子進(jìn)程沒有自己的終端或控制臺(tái)。它的所有標(biāo)準(zhǔn) io(即 stdin超燃,stdout区拳,stderr)操作都將通過三個(gè)流 (getOutputStream(),getInputStream()意乓,getErrorStream()) 重定向到父進(jìn)程樱调。父進(jìn)程使用這些流來提供到子進(jìn)程的輸入和獲得從子進(jìn)程的輸出。因?yàn)橛行┍緳C(jī)平臺(tái)僅針對(duì)標(biāo)準(zhǔn)輸入和輸出流提供有限的緩沖區(qū)大小洽瞬,如果讀寫子進(jìn)程的輸出流或輸入流迅速出現(xiàn)失敗,則可能導(dǎo)致子進(jìn)程阻塞业汰,甚至產(chǎn)生死鎖伙窃。
當(dāng)沒有 Process 對(duì)象的更多引用時(shí),不是刪掉子進(jìn)程样漆,而是繼續(xù)異步執(zhí)行子進(jìn)程为障。
二、API預(yù)覽
destroy() 殺掉子進(jìn)程放祟。 exitValue() 返回子進(jìn)程的出口值鳍怨。 InputStream getErrorStream() 獲得子進(jìn)程的錯(cuò)誤流。 InputStream getInputStream() 獲得子進(jìn)程的輸入流跪妥。 OutputStream getOutputStream() 獲得子進(jìn)程的輸出流鞋喇。 waitFor() 導(dǎo)致當(dāng)前線程等待,如果必要眉撵,一直要等到由該 Process 對(duì)象表示的進(jìn)程已經(jīng)終止侦香。
三、如何創(chuàng)建Process對(duì)象纽疟,一般有一下兩種方法:
**
**
1罐韩、每個(gè) ProcessBuilder 實(shí)例管理一個(gè)進(jìn)程屬性集。start() 方法利用這些屬性創(chuàng)建一個(gè)新的 Process 實(shí)例污朽。start() 方法可以從同一實(shí)例重復(fù)調(diào)用散吵,以利用相同的或相關(guān)的屬性創(chuàng)建新的子進(jìn)程。(ProcessBuilder這個(gè)是JDK5中新添加的final類,詳細(xì)請(qǐng)參看“深入研究java.lang.ProcessBuilder類”一文矾睦。
2晦款、Runtime.exec() 方法創(chuàng)建一個(gè)本機(jī)進(jìn)程,并返回 Process 子類的一個(gè)實(shí)例顷锰。詳細(xì)請(qǐng)參看“深入研究java.lang.Runtime類”一文柬赐。
四、實(shí)例
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* 控制臺(tái)處理工具箱
*
* @author leizhimin 2009-6-25 14:12:14
*/
public final class CmdToolkit {
private static Log log = LogFactory.getLog(CmdToolkit.class);
private CmdToolkit() {
}
/**
* 讀取控制命令的輸出結(jié)果
*
* @param cmd 命令
* @param isPrettify 返回的結(jié)果是否進(jìn)行美化(換行)官紫,美化意味著換行肛宋,默認(rèn)不進(jìn)行美化,當(dāng)此參數(shù)為null時(shí)也不美化,
* @return 控制命令的輸出結(jié)果
* @throws IOException
*/
public static String readConsole(String cmd, Boolean isPrettify) throws IOException {
StringBuffer cmdout = new StringBuffer();
log.info("執(zhí)行命令:" + cmd);
Process process = Runtime.getRuntime().exec(cmd); //執(zhí)行一個(gè)系統(tǒng)命令
InputStream fis = process.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String line = null;
if (isPrettify == null || isPrettify) {
while ((line = br.readLine()) != null) {
cmdout.append(line);
}
} else {
while ((line = br.readLine()) != null) {
cmdout.append(line).append(System.getProperty("line.separator"));
}
}
log.info("執(zhí)行系統(tǒng)命令后的結(jié)果為:\n" + cmdout.toString());
return cmdout.toString().trim();
}
}