1. 程式人生 > >Java中使用ProcessBuilder啟動、管理應用程式

Java中使用ProcessBuilder啟動、管理應用程式

1.概述

ProcessBuilder類是J2SE 1.5在java.lang中新新增的一個新類,此類用於建立作業系統程序,它提供一種啟動和管理程序(也就是應用程式)的方法。在J2SE 1.5之前,都是由Process類處來實現程序的控制管理。

每個 ProcessBuilder 例項管理一個程序屬性集。它的start() 方法利用這些屬性建立一個新的 Process 例項。

使用ProcessBuilder比使用Process的好處在於,我們不僅僅可以去執行一個應用程式,還可以對執行程序進行更多的管理工作,比如:獲取程序的執行資訊,包括標準輸出、標準錯誤輸出;設定當前工作目錄;改變環境引數。

2.屬性

2.1 redirectErrorStream屬性

最初,此屬性為 false,意思是子程序的標準輸出和錯誤輸出被髮送給兩個獨立的流,這些流可以通過 Process.getInputStream() 和 Process.getErrorStream() 方法來訪問。如果將值設定為 true,標準錯誤將與標準輸出合併。這使得關聯錯誤訊息和相應的輸出變得更容易。在此情況下,合併的資料可從 Process.getInputStream() 返回的流讀取,而從 Process.getErrorStream() 返回的流讀取將直接到達檔案尾。

2.簡單測試類

package
com.process; import java.util.ArrayList; import java.util.List; /** * Created by lcc on 2018/9/14. */ public class ProcessBuilderTest { public static void main(String[] args){ List<String> command = new ArrayList<String>(); command.add("/bin/echo"); command.add("'aa'"
); command.add(">"); command.add("/Users/lcc/IdeaProjects/AllTest/aaaa.txt"); try { ProcessBuilder builder = new ProcessBuilder(command); builder.command(command); Process p = builder.start(); if(p.isAlive()){ // waitfor()等待的是子程序的退出 p.waitFor(); } } catch (Exception e) { e.printStackTrace(); } } }

直接執行可以看到

lcc@lcc AllTest$ ll  | grep aa* 
-rw-r--r--   1 lcc  staff     3 Sep 14 21:44 aaaa.txt
lcc@lcc AllTest$ 

3.原始碼

    public ProcessBuilder(List<String> command) {
        if (command == null)
            throw new NullPointerException();
        this.command = command;
    }

    public ProcessBuilder(String... command) {
        this.command = new ArrayList<>(command.length);
        for (String arg : command)
            this.command.add(arg);
    }


    public ProcessBuilder command(List<String> command) {
        if (command == null)
            throw new NullPointerException();
        this.command = command;
        return this;
    }


    public ProcessBuilder command(String... command) {
        this.command = new ArrayList<>(command.length);
        for (String arg : command)
            this.command.add(arg);
        return this;
    }

可以看到接受兩種型別的引數
List<String> command

如:上面的程式

String... command
如:

new ProcessBuilder("mysqldump.exe",dbName,"-h"+host,"-u"+username,"-p"+password);

4. ProcessBuilder呼叫外部命令 並返回結果

package com.process;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by lcc on 2018/9/14.
 */
public class ProcessBuilderTest {


    public static void main(String[] args){
        List<String> command = new ArrayList<>();
        command.add("/bin/ls");
        command.add("/Users/lcc/IdeaProjects/AllTest/");
        try {
            ProcessBuilder builder = new ProcessBuilder(command);
            builder.redirectErrorStream(true);
            Process process = builder.start();
            InputStream in=process.getInputStream();
            byte[] re=new byte[1024];
            while (in.read(re)!= -1) {
                System.out.println("==>"+new String(re));
            }
            in.close();
            if(process.isAlive()){
                process.waitFor();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

執行結果

這裡寫圖片描述

最後的一堆空格不知道咋回事

5.傳參

package com.process;

import java.io.File;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by lcc on 2018/9/14.
 */
public class ProcessBuilderTest {


    public static void main(String[] args){
        test3();
    }


    private static void test3() {

        List<String> command = new ArrayList<>();
        command.add("java");
        command.add("-cp");
        command.add(".:/Users/lcc/IdeaProjects/AllTest/druid_test/target/druid_test-1.0-SNAPSHOT.jar");
        command.add("com.sql.parse.self.MainTest");
        command.add("aaaa");
        try {
            ProcessBuilder builder = new ProcessBuilder(command);
            builder.redirectErrorStream(true);
            Process process = builder.start();
            InputStream in=process.getInputStream();
            byte[] re=new byte[1024];
            while (in.read(re)!= -1) {
                System.out.println("==>"+new String(re));
            }
            in.close();
            if(process.isAlive()){
                process.waitFor();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


    }


}

jar包中的main

package com.sql.parse.self;

/**
 * Created by lcc on 2018/9/15.
 */
public class MainTest {

    public static void main(String[] args) {

        System.out.println("lcc="+args[0]);
    }

}

輸出結果

==>lcc=aaaa

參考: