Java ProcessBuilder类学习

x33g5p2x  于2022-05-23 转载在 Java  
字(4.2k)|赞(0)|评价(0)|浏览(370)

一、ProcessBuilder基础

1、ProcessBuilder类

1.1 概述

ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它提供一种启动和管理进程(也就是应用程序)的方法。在J2SE 1.5之前,都是由Process类处理实现进程的控制管理。

每个ProcessBuilder 实例管理一个进程属性集,它的start()方法利用这些属性创建一个新的 Process 实例。start()方法可以从同一实例重复调用,以利用相同的或相关的属性创建新的子进程。

1.2 进程属性

  • 命令 command
    表示要调用的外部程序文件及其参数(如果有)。
  • 环境 environment
    从变量到值依赖于系统的映射。初始值是当前进程环境的一个副本(请参阅System.getenv())。
  • 工作目录 working directory
    默认值是当前进程的当前工作目录,通常根据系统属性 user.dir 来命名。
  • redirectErrorStream属性
    此属性为 false意思是子进程的标准输出和错误输出被发送给两个独立的流,这些流可以通过 Process.getInputStream()Process.getErrorStream()方法来访问。如果将值设置为 true,标准错误将与标准输出合并,在此情况下,合并的数据可从 Process.getInputStream() 返回的流读取,而从 Process.getErrorStream() 返回的流读取将直接到达文件尾。
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
Map<String, String> env = pb.environment();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
pb.directory("myDir");
Process p = pb.start();

2、Process类

2.1 概述

Process类是一个抽象类(所有的方法均是抽象的),封装了一个进程(即一个执行程序)。

Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。创建的子进程没有自己的终端或控制台。它的所有标准 io(即 stdin、stdout 和 stderr)操作都将通过三个流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父进程。父进程使用这些流来提供到子进程的输入和获得从子进程的输出。

2.2 Process抽象类

  • destroy()
    杀掉子进程。
  • exitValue()
    返回子进程的出口值。
  • InputStream getErrorStream()
    获得子进程的错误流。
  • InputStream getInputStream()
    获得子进程的输入流。
  • OutputStream getOutputStream()
    获得子进程的输出流。
  • waitFor()
    导致当前线程等待,如果必要,一直要等到由该 Process 对象表示的进程已经终止

同时Process对象可以获得进程句柄,从而可以获得进程ID、父进程、子进程等信息

2.3 创建Process对象方式

  • 使用命令名和命令的参数选项构造ProcessBuilder对象,它的start方法执行命令,启动一个进程,返回一个Process对象
  • Runtime.exec()方法创建一个本机进程,并返回 Process 子类的一个实例

3、ProcessBuilder与Runtime.exec()异同

3.1 相同点

ProcessBuilder.start()Runtime.exec() 方法都被用来创建一个操作系统进程(执行命令行操作),并返回 Process 子类的一个实例,该实例可用来控制进程状态并获得相关信息

3.2 不同点

ProcessBuilder.start()Runtime.exec()传递的参数有所不同

Runtime.exec()可接受一个单独的字符串,这个字符串是通过空格来分隔可执行命令程序和参数的;也可以接受字符串数组参数。而ProcessBuilder的构造函数是一个字符串列表或者数组。列表中第一个参数是可执行命令程序,其他的是命令行执行是需要的参数。

二、ProcessBuilder实战

1、API介绍

构造方法

  • ProcessBuilder(List command)
    利用指定的操作系统程序和参数构造一个进程生成器。
  • ProcessBuilder(String… command)
    利用指定的操作系统程序和参数构造一个进程生成器。

方法

  • command()
    返回此进程生成器的操作系统程序和参数。
  • command(List command)
    设置此进程生成器的操作系统程序和参数。
  • command(String… command)
    设置此进程生成器的操作系统程序和参数。
  • directory()
    返回此进程生成器的工作目录。
  • directory(File directory)
    设置此进程生成器的工作目录。
  • environment()
    返回此进程生成器环境的字符串映射视图。 environment方法获得运行进程的环境变量,得到一个Map,可以修改环境变量
  • redirectErrorStream()
    通知进程生成器是否合并标准错误和标准输出。
  • redirectErrorStream(boolean redirectErrorStream)
    设置此进程生成器的 redirectErrorStream 属性。
  • start()
    使用此进程生成器的属性启动一个新进程。

2、实战demo

//Runtime.exec()进行创建
public static void main(String[] args) {
        try {
            Process process = Runtime.getRuntime().exec("ipconfig /all");
            InputStream is = process.getInputStream();
            InputStreamReader isr =new InputStreamReader(is, "gbk");

            BufferedReader br = new BufferedReader(isr);

            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }

            int exitCode = process.waitFor();
            System.out.println(exitCode);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
public static void main(String[] args) {
        ProcessBuilder processBuilder = new ProcessBuilder();
        // System.out.println(processBuilder.directory());
        // System.out.println(processBuilder.environment());
        //processBuilder.command("ping","127.0.0.1");
        processBuilder.command("ipconfig","/all");
        //将标准输入流和错误输入流合并,通过标准输入流读取信息
        processBuilder.redirectErrorStream(true);
        try {
            //启动进程
            Process start = processBuilder.start();
            //获取输入流
            InputStream inputStream = start.getInputStream();
            //转成字符输入流
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "gbk");
            int len = -1;
            char[] c = new char[1024];
            StringBuffer outputString = new StringBuffer();
            //读取进程输入流中的内容
            while ((len = inputStreamReader.read(c)) != -1) {
                String s = new String(c, 0, len);
                outputString.append(s);
                System.out.print(s);
            }
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
public static void main(String[] args) throws IOException {
        ProcessBuilder processBuilder = new ProcessBuilder("cmd","/c","dir");
        processBuilder.directory(new File("D:/"));
        Process process = processBuilder.start();
        BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
    }

相关文章