1. 程式人生 > >ProcessBuilder 、Runtime和Process 的區別

ProcessBuilder 、Runtime和Process 的區別

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來真正執行操作的

  1. import java.io.BufferedReader;  
  2. import java.io.File;  
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.io.InputStreamReader;  
  6. import java.util.Map;  
  7. publicclass ProcessBuilderTest {  
  8.     publicstaticvoid restart() throws IOException {  
  9.         // Runtime 例子
  10.         Process p;  
  11.         // test.bat中的命令是ipconfig/all
  12.         String cmd = "c:\\test\\test.bat";  
  13.         try {  
  14.             // 執行命令
  15.             p = Runtime.getRuntime().exec(cmd);  
  16.             // 取得命令結果的輸出流
  17.             InputStream fis = p.getInputStream();  
  18.             // 用一個讀輸出流類去讀
  19.             InputStreamReader isr = new InputStreamReader(fis);  
  20.             // 用緩衝器讀行
  21.             BufferedReader br = new BufferedReader(isr);  
  22.             String line = null;  
  23.             // 直到讀完為止
  24.             while ((line = br.readLine()) != null) {  
  25.                 System.out.println(line);  
  26.             }  
  27.         } catch (IOException e) {  
  28.             e.printStackTrace();  
  29.         }  
  30.         // ProcessBuilder 例子 Java程式自重啟
  31.         // 用一條指定的命令去構造一個程序生成器
  32.         ProcessBuilder pb = new ProcessBuilder("java""-jar""Test3.jar");  
  33.         // 讓這個程序的工作區空間改為F:\dist
  34.         // 這樣的話,它就會去F:\dist目錄下找Test.jar這個檔案
  35.         pb.directory(new File("F:\\dist"));  
  36.         // 得到程序生成器的環境 變數,這個變數我們可以改,
  37.         // 改了以後也會反應到新起的程序裡面去
  38.         Map<String, String> map = pb.environment();  
  39.         Process p1 = pb.start();  
  40.         // 然後就可以對p做自己想做的事情了
  41.         // 自己這個時候就可以退出了
  42.         System.exit(0);  
  43.     }  
  44. }  

  1. class PBDemo {   
  2.         publicstaticvoid main(String args[]) {   
  3.                 try {   
  4.                         ProcessBuilder proc = new ProcessBuilder("notepad.exe""testfile");   
  5.                         proc.start();   
  6.                 } catch (Exception e) {   
  7.                         System.out.println("Error executing notepad.");   
  8.                 }   
  9.         }   
  10. }