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

     

    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.");
                    }
            }
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM