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 command = new ArrayList();
        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 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 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 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 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();
        }
    }

}

运行结果

Java中使用ProcessBuilder启动、管理应用程序_第1张图片

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

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 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

参考:

https://www.cnblogs.com/ct-blog/articles/5409982.html

你可能感兴趣的:(后端-语言-java基础)