Java中使用ProcessBuilder啟動、管理應用程式
阿新 • • 發佈:2019-02-13
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
參考: