1、版本原因
ProcessBuilder是從java1.5加進來的,而exec系列方法是從1.0開始就有的,后續版本不斷的重載這個方法,到了1.5已經有6個之多。
2、ProcessBuilder、Runtime和Process 三者之間的聯系
ProcessBuilder.start() 和 Runtime.exec() 方法都被用來創建一個操作系統進程(執行命令行操作),並返回 Process 子類的一個實例,該實例可用來控制進程狀態並
獲得相關信息。
3、ProcessBuilder和Process區別
既然有Process類,那為什么還要發明個ProcessBuilder類呢?ProcessBuilder和Process兩個類有什么區別呢?
首先,每個進程生成器(即ProcessBuilder對象)管理這些進程屬性:
命令:是一個字符串列表,它表示要調用的外部程序文件及其參數(如果有)。在此,表示有效的操作系統命令的字符串列表是依賴於系統的。例如,每一個總體變
量,通常都要成為此列表中的元素,但有一些操作系統,希望程序能自己標記命令行字符串——在這種系統中,Java 實現可能需要命令確切地包含這兩個元素。
環境:是從變量 到值 的依賴於系統的映射。初始值是當前進程環境的一個副本(請參閱 System.getenv())。
工作目錄:默認值是當前進程的當前工作目錄,通常根據系統屬性 user.dir 來命名。
redirectErrorStream 屬性:最初,此屬性為 false,意思是子進程的標准輸出和錯誤輸出被發送給兩個獨立的流,這些流可以通過 Process.getInputStream() 和
Process.getErrorStream() 方法來訪問。如果將值設置為 true,標准錯誤將與標准輸出合並。這使得關聯錯誤消息和相應的輸出變得更容易。在此情況下,合並的數據可從 Process.getInputStream() 返回的流讀取,而從 Process.getErrorStream() 返回的流讀取將直接到達文件尾。
所以就有,ProcessBuilder為進程提供了更多的控制,例如,可以設置當前工作目錄,還可以改變環境參數。而Process的功能相對來說簡單的多。
ProcessBuilder是一個final類,有兩個帶參數的構造方法,你可以通過構造方法來直接創建ProcessBuilder的對象。而Process是一個抽象類,一般都通過Runtime.ex
ec()和ProcessBuilder.start()來間接創建其實例。
注意:
修改進程構建器的屬性將影響后續由該對象的 start() 方法啟動的進程,但從不會影響以前啟動的進程或 Java 自身的進程。
ProcessBuilder類不是同步的。如果多個線程同時訪問一個 ProcessBuilder,而其中至少一個線程從結構上修改了其中一個屬性,它必須 保持外部同步。
4、ProcessBuilder 、Runtime區別
ProcessBuilder.start() 和 Runtime.exec()傳遞的參數有所不同,Runtime.exec()可接受一個單獨的字符串,這個字符串是通過空格來分隔可執行命令程序和參數的;
也可以接受字符串數組參數。而ProcessBuilder的構造函數是一個字符串列表或者數組。列表中第一個參數是可執行命令程序,其他的是命令行執行是需要的參數。
通過查看JDK源碼可知,Runtime.exec最終是通過調用ProcessBuilder來真正執行操作的。
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Map;
public class ProcessBuilderTest {
public static void restart() throws IOException {
// Runtime 例子
Process p;
// test.bat中的命令是ipconfig/all
String cmd = "c:\\test\\test.bat";
try {
// 執行命令
p = Runtime.getRuntime().exec(cmd);
// 取得命令結果的輸出流
InputStream fis = p.getInputStream();
// 用一個讀輸出流類去讀
InputStreamReader isr = new InputStreamReader(fis);
// 用緩沖器讀行
BufferedReader br = new BufferedReader(isr);
String line = null;
// 直到讀完為止
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// ProcessBuilder 例子 Java程序自重啟
// 用一條指定的命令去構造一個進程生成器
ProcessBuilder pb = new ProcessBuilder("java", "-jar", "Test3.jar");
// 讓這個進程的工作區空間改為F:\dist
// 這樣的話,它就會去F:\dist目錄下找Test.jar這個文件
pb.directory(new File("F:\\dist"));
// 得到進程生成器的環境 變量,這個變量我們可以改,
// 改了以后也會反應到新起的進程里面去
Map<String, String> map = pb.environment();
Process p1 = pb.start();
// 然后就可以對p做自己想做的事情了
// 自己這個時候就可以退出了
System.exit(0);
}
}
class PBDemo {
public static void main(String args[]) {
try {
ProcessBuilder proc = new ProcessBuilder("notepad.exe", "testfile");
proc.start();
} catch (Exception e) {
System.out.println("Error executing notepad.");
}
}
}