ProcessBuilder 创建操作系统进程

目录

ProcessBuilder 概述

方法概述

API 测试

路径空格说明


ProcessBuilder 概述

1、public final class java.lang.ProcessBuilder extends Object :此类用于创建操作系统进程。 

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

3、此类不是同步的,如果多个线程同时访问一个 ProcessBuilder,而其中至少一个线程从结构上修改了其中一个属性,它必须保持外部同步。

4、此类从 JDK 5 开始推出,用于替代之前的 Runtime 类,可以参考《Process 详解 1》、《Runtime 详解四》

5、注意事项:使用 Runtime 时,只要程序和参数的路径中没有空格是可以写到一个参数中的,默认按空格分隔;但是ProcessBuilder 设置程序和参数必须分开写,否则报错:“系统找不到指定的文件”。

启动使用默认工作目录和环境的新进程很容易: 

Process p = new ProcessBuilder("myCommand", "myArg").start(); 

构造函数

一共重载了两个构造函数,一个参数是 list,一个是 array。

public ProcessBuilder (List command)

1)利用指定的操作系统程序和参数构造一个进程生成器
2)此构造方法不会 制作一份 command 列表的副本
3)不会检查 command 是否为一个有效的操作系统命令。
4、参数:command - 包含程序及其参数的列表 ,程序和参数必须分开写
5、抛出: NullPointerException - 如果参数为 null

public ProcessBuilder (String... command)

1、利用指定的操作系统程序和参数构造一个进程生成器。
2、一个有用的构造方法,它将进程生成器的命令设置为与 command 数组包含相同字符串的字符串列表,且顺序相同。
3、不会检查 command 是否为一个有效的操作系统命令。
4、参数:command - 包含程序及其参数的字符串数组,程序和参数必须分开写

方法概述

Modifier and Type Method and Description
List command()返回此流程构建器的操作系统程序和参数。
ProcessBuilder command(List command) 设置此流程构建器的操作系统程序和参数。
ProcessBuilder command(String... command)设置此流程构建器的操作系统程序和参数。
File directory()返回此进程构建器的工作目录。
ProcessBuilder directory(File directory)设置此进程构建器的工作目录。
Map environment()返回此流程构建器环境的字符串映射视图。
ProcessBuilder inheritIO()将子进程标准I / O的源和目标设置为与当前Java进程相同。
ProcessBuilder.Redirect redirectError()返回此流程构建器的标准错误目标。
ProcessBuilder redirectError(File file)将此流程构建器的标准错误目标设置为文件。
ProcessBuilder redirectError(ProcessBuilder.Redirect destination)设置此流程构建器的标准错误目标。
boolean redirectErrorStream()告诉这个进程构建器是否合并标准错误和标准输出。
ProcessBuilder redirectErrorStream(boolean redirectErrorStream)设置此过程构建器的 redirectErrorStream属性。
ProcessBuilder.Redirect redirectInput()返回此流程构建器的标准输入源。
ProcessBuilder redirectInput(File file)将此流程构建器的标准输入源设置为文件。
ProcessBuilder redirectInput(ProcessBuilder.Redirect source)设置此流程构建器的标准输入源。
ProcessBuilder.Redirect redirectOutput()返回此流程构建器的标准输出目标。
ProcessBuilder redirectOutput(File file)将此流程构建器的标准输出目标设置为文件。
ProcessBuilder redirectOutput(ProcessBuilder.Redirect destination)设置此流程构建器的标准输出目标。
Process start()使用此流程构建器的属性启动新进程。

更多 API 可以参考官方文档:http://www.matools.com/api/java8

public Process start() throws IOException

1)使用此进程生成器的属性启动一个新进程

2)此方法检查命令是否为一条有效的操作系统命令,哪条命令是有效的呢?这取决于系统,但至少命令必须是非空字符串的非空列表。 

3)返回:一个新的 Process 对象,用于管理子进程 

API 测试

启动 windows 自带的计算器

1、在 C:/windows/System32 目录下面,windows 系统自带了很多应用程序,如记事本、计算器、画图、shutdown 等等。

2、下面演示调用系统程序,不加参数,新开的程序就相当于一个子进程。

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
 * Created by Administrator on 2019/2/26 0026.
 */
public class APITest {
    private static final Logger logger = Logger.getGlobal();//日志记录器

    public static void main(String[] args) {
        try {
            List paramList = new ArrayList<>();
            //启动 windows 的计算器程序,第一个参数必须是可执行程序
            paramList.add("C:\\Windows\\System32\\calc.exe");
            /** 创建ProcessBuilder对象,设置指令列表*/
            ProcessBuilder processBuilder = new ProcessBuilder(paramList);
            logger.info("启动子进程...");
            Process process = processBuilder.start();
            logger.info("子进程启动完成...");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

启动 Potplayer 播放一个指定的视频文件

1、各种安装的软件都可以进行打开,这里比如安装好的视频播放器,我这里安装的是 PotPlayer 播放器,路径为:D:\PotPlayer\PotPlayerMini.exe

2、很多程序是支持在 cmd 调用时传递参数的,如 chrome.exe 浏览器等等,potPlayer 也可以在调用时指定参数。

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
 * Created by Administrator on 2019/2/26 0026.
 */
public class APITest {
    private static final Logger logger = Logger.getGlobal();//日志记录器

    public static void main(String[] args) {
        try {
            List paramList = new ArrayList<>();
            //启动 windows 上安装好的 potplayer 播放器,设置 exe 路径,路径必须存在
            //第一个参数必须是可执行程序
            paramList.add("D:\\PotPlayer\\PotPlayerMini.exe");
            //设置 potplayer 将要播放的文件,也就是给 potplayer 传递的参数,文件必须存在
            paramList.add("E:\\Study_Note\\Spring Cloud\\视频\\第1天\\4 服务提供者与服务消费者.avi");

            /** 创建ProcessBuilder对象,设置指令列表*/
            ProcessBuilder processBuilder = new ProcessBuilder(paramList);
            logger.info("启动子进程...");
            Process process = processBuilder.start();
            logger.info("子进程启动完成...");
            for (int i = 5; i > 0; i--) {
                logger.info((i) + " 秒后结束子进程...");
                Thread.sleep(1000);
            }
            process.destroyForcibly();//强行终结开启的子进程
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

然而并不是,所有的子进程,都能这么轻易杀死,对于需要在某些特定时刻杀死子进程的,可以参考:https://blog.csdn.net/wangmx1993328/article/details/80832181#t7 中的“杀死子进程 -> 解决方式 2” 部分。

使用 cmd 命令 ping 目标主机,然后将结果信息存放在指定文件中

ping 目标主机:属于 windows 指令,如果自己的电脑和目标主机之间网络通畅,则会返回成功信息,否则返回失败信息。

import javax.swing.filechooser.FileSystemView;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
/**
 * Created by Administrator on 2019/2/26 0026.
 */
public class APITest {
    private static final Logger logger = Logger.getGlobal();//日志记录器

    public static void main(String[] args) throws IOException {
        List paramList = new ArrayList<>();
        //使用 cmd 命令 ping 远程主机
        //第一个参数必须是可执行程序,cmd也是一个可执行程序,位于 C:/Windows/System32目录下
        paramList.add("cmd");
        paramList.add("/c");
        paramList.add("ping www.taobao.com");//也可以是ip,如 paramList.add("ping 114.114.114.114");

        /** 创建ProcessBuilder对象,设置指令列表*/
        ProcessBuilder processBuilder = new ProcessBuilder(paramList);

        //获取桌面路径,如:C:\Users\Administrator.SC-201707281232\Desktop
        File desktopFile = FileSystemView.getFileSystemView().getHomeDirectory();

        //创建子进程输出信息的存放文件,文件不存在时,会自动创建
        File outputFile = new File(desktopFile, "output.txt");
        //返回此流程构建器的标准输出目标,意思是将来输出信息全部放在这个目标中
        processBuilder = processBuilder.redirectOutput(outputFile);
        processBuilder.start();//启动进程构建器
        logger.info("子进程执行消息存放在:" + processBuilder.redirectOutput().file().getPath());
    }
}

4)directory(File directory)  设置此进程构建器的工作目录,注意它是为参数列表中程序参数设置工作目录,而不是程序的工作目录,下面通过实例理解。

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

/**
 * Created by Administrator on 2019/2/26 0026.
 */
public class APITest {
    private static final Logger logger = Logger.getGlobal();//日志记录器

    public static void main(String[] args) throws IOException {
        List paramList = new ArrayList<>();
        paramList.add("C:/windows/system32/notepad.exe");//启动系统的记事本,第一个参数必须是可执行程序
        //打开 E:/wmx/test/123.txt 文件,文件必须存在
        //应该在 start 之前切换工作目录到 E:/wmx/test
        paramList.add("123.txt");
        ProcessBuilder pb = new ProcessBuilder(paramList);
        //切换进程构建器的工作目录到 E:/wmx/test 下,这样上面才能简写 123.txt时找到文件
        //必须注意的是 directory 是为paramList中的参数 "123.txt" 设置的工作目录,,而不是程序 "C:/windows/system32/notepad.exe"
        //程序要么就是写全路径,要么就是配置系统环境变量才能写简称,如 calc、notepad 等
        pb.directory(new File("E:/wmx/test/"));
        pb.start();//开启子进程
        logger.info(pb.directory() + ":当前工作目录");//默认情况下,未设置时,输出为 null
    }
}

路径空格说明

1)如下使用 Office 的 Word.exe 打开一个 docx 文件,Word.exe 与 .docx 文件路径有空格都是可以的,Word.exe 与 .docx 分别占一个元素:

正确:[cmd, /c, C:\Program Files (x86)\Microsoft Office\root\Office16\WINWORD.EXE, E:\wmx\MR软件说明书.docx]

2)如下使用 PotPlayer 播放一个 mp4文件,mp4文件路径含有空格,可以将空格路径作为一个元素,也可以将路径空格位置切分为多个元素:
正确:[cmd, /c, D:\PotPlayer\PotPlayerMini.exe, E:\wmx\w s\sh k\8.mp4]
正确:[cmd, /c, D:\PotPlayer\PotPlayerMini.exe, E:\wmx\w, s\sh, k\8.mp4]

3)如下的本意是想让 Chrome 浏览器全屏模式打开一个地址,因为 --kiosk 与后面的浏览器地址一共是两个参数,所以写法一正确,写法二错误。

正确:[cmd, /c, C:/Program Files (x86)/Google/Chrome/Application/chrome.exe, --kiosk, http://www.baidu.com]
错误:[cmd, /c, C:/Program Files (x86)/Google/Chrome/Application/chrome.exe, --kiosk http://www.baidu.com]

 

你可能感兴趣的:(Java_SE)