ProcessBuilder
java.lang.Object
|—java.lang.ProcessBuilder
public final class ProcessBuilder
extends Object
此类用于创建操作系统进程。
每个 ProcessBuilder 实例管理一个流程属性的集合。 start() 方法使用这些属性创建一个新的 Process 实例。 可以从同一个实例重复调用 start() 方法来创建具有相同或相关属性的新子流程。
每个流程构建器都管理这些流程属性:
- 一个命令,一个字符串列表,表示要调用的外部程序文件及其参数(如果有)。 哪些字符串列表代表有效的操作系统命令取决于系统。 例如,每个概念参数通常是该列表中的一个元素,但在某些操作系统中,程序需要自己标记命令行字符串——在这样的系统上,Java 实现可能需要命令恰好包含两个元素。
- 环境,它是从变量到值的系统相关映射。 初始值是当前进程环境的副本。
- 一个工作目录。 默认值为当前进程的当前工作目录,通常是系统属性user.dir命名的目录。
- 标准输入源 默认情况下,子进程从管道读取输入。 Java 代码可以通过 Process#getOutputStream() 返回的输出流访问此管道。 但是,标准输入可以使用redirectInput 重定向到另一个源。 在这种情况下,Process#getOutputStream() 将返回一个空输出流,其中:
- OutputStream#write(int) 方法总是抛出 IOException
- OutputStream#close() 方法什么也不做
- 标准输出和标准错误的目的地。 默认情况下,子进程将标准输出和标准错误写入管道。 Java 代码可以通过 Process#getInputStream() 和 Process#getErrorStream() 返回的输入流访问这些管道。 但是,标准输出和标准错误可以使用redirectOutput 和redirectError 重定向到其他目的地。 在这种情况下, Process#getInputStream() 和/或 Process#getErrorStream() 将返回一个空输入流,其中:
- InputStream#read() 方法总是返回 -1
- InputStream#available() 方法总是返回 0
- InputStream#close() 方法什么也不做
- 一个 redirectErrorStream 属性。 最初,此属性为 false,这意味着子进程的标准输出和错误输出被发送到两个单独的流,可以使用 Process#getInputStream() 和 Process#getErrorStream() 方法访问它们。
如果该值设置为 true,则:
- 标准错误与标准输出合并并始终发送到相同的目的地(这使得将错误消息与相应的输出关联起来更容易)
- 标准错误和标准输出的共同目的地可以使用redirectOutput重定向
- 在创建子进程时,任何由 redirectError 方法设置的重定向都会被忽略
- 从 Process#getErrorStream() 返回的流将始终为空输入流
修改进程构建器的属性将影响随后由该对象的 start() 方法启动的进程,但不会影响先前启动的进程或 Java 进程本身。
大多数错误检查由 start() 方法执行。 可以修改对象的状态以使 start() 失败。 例如,将 command 属性设置为空列表不会引发异常,除非调用 start()。
请注意,此类不同步。 如果多个线程同时访问一个 ProcessBuilder 实例,并且至少有一个线程在结构上修改了其中一个属性,则必须在外部进行同步。
启动一个使用默认工作目录和环境的新进程很容易:
Process p = new ProcessBuilder("myCommand", "myArg").start();
下面是一个示例,它使用修改后的工作目录和环境启动进程,并将标准输出和错误重定向到附加到日志文件中:
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(new File("myDir"));
File log = new File("log");
pb.redirectErrorStream(true);
pb.redirectOutput(Redirect.appendTo(log));
Process p = pb.start();
assert pb.redirectInput() == Redirect.PIPE;
assert pb.redirectOutput().file() == log;
assert p.getInputStream().read() == -1;
要使用一组显式环境变量启动进程,请在添加环境变量之前首先调用 Map.clear()。
嵌套类摘要
修饰符和类型 | 类 | 描述 |
---|---|---|
static class | ProcessBuilder.Redirect | 表示子流程输入的来源或子流程输出的目的地。 |
构造函数摘要
构造函数 | 描述 |
---|---|
ProcessBuilder(String… command) | 使用指定的操作系统程序和参数构造一个进程构建器。 |
ProcessBuilder(ListString command) | 使用指定的操作系统程序和参数构造一个进程构建器。 |
方法总结
修饰符和类型 | 方法 | 描述 |
---|---|---|
ListString | command() | 返回此进程构建器的操作系统程序和参数。 |
ProcessBuilder | command(String… command) | 设置此进程构建器的操作系统程序和参数。 |
ProcessBuilder | command(ListString command) | 设置此进程构建器的操作系统程序和参数。 |
File | directory() | 返回此流程构建器的工作目录。 |
ProcessBuilder | directory(File directory) | 设置此流程构建器的工作目录。 |
MapString,String | 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() | 使用此流程构建器的属性启动一个新流程。 |
从类 java.lang.Object 继承的方法 |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
构造函数详细信息
ProcessBuilder
public ProcessBuilder(ListString command)
使用指定的操作系统程序和参数构造一个进程构建器。 此构造函数不会复制命令列表。 列表的后续更新将反映在流程构建器的状态中。 不检查命令是否对应于有效的操作系统命令。
参数:
参数名称 | 参数描述 |
---|---|
command | 包含程序及其参数的列表 |
Throws:
Throw名称 | Throw描述 |
---|---|
NullPointerException | 如果参数为空 |
ProcessBuilder
public ProcessBuilder(String… command)
使用指定的操作系统程序和参数构造一个进程构建器。 这是一个方便的构造函数,它将进程构建器的命令设置为一个字符串列表,其中包含与命令数组相同的字符串,顺序相同。 不检查命令是否对应于有效的操作系统命令。
参数:
参数名称 | 参数描述 |
---|---|
command | 包含程序及其参数的字符串数组 |
方法详情
command
public ProcessBuilder command(ListString command)
设置此进程构建器的操作系统程序和参数。 此方法不会复制命令列表。 列表的后续更新将反映在流程构建器的状态中。 不检查命令是否对应于有效的操作系统命令。
参数:
参数名称 | 参数描述 |
---|---|
command | 包含程序及其参数的列表 |
返回:
此流程构建器
Throws:
Throw名称 | Throw描述 |
---|---|
NullPointerException | 如果参数为空 |
command
public ProcessBuilder command(String… command)
设置此进程构建器的操作系统程序和参数。 这是一种方便的方法,它将命令设置为一个字符串列表,其中包含与命令数组相同的字符串,顺序相同。 不检查命令是否对应于有效的操作系统命令。
参数:
参数名称 | 参数描述 |
---|---|
command | 包含程序及其参数的字符串数组 |
返回:
此流程构建器
command
public ListString command()
返回此进程构建器的操作系统程序和参数。 返回的列表不是副本。 列表的后续更新将反映在此流程构建器的状态中。
返回:
此流程构建器的程序及其参数
environment
public MapString,String environment()
返回此流程构建器环境的字符串映射视图。每当创建流程构建器时,都会将环境初始化为当前流程环境的副本(请参阅 System#getenv())。随后由该对象的 start() 方法启动的子进程将使用该映射作为它们的环境。
返回的对象可以使用普通的 Map 操作进行修改。这些修改将对通过 start() 方法启动的子进程可见。两个 ProcessBuilder 实例始终包含独立的流程环境,因此对返回映射的更改将永远不会反映在任何其他 ProcessBuilder 实例或 System#getenv 返回的值中。
如果系统不支持环境变量,则返回一个空映射。
返回的映射不允许空键或值。尝试插入或查询是否存在空键或值将引发 NullPointerException。尝试查询是否存在非 String 类型的键或值将引发 ClassCastException。
返回地图的行为取决于系统。系统可能不允许修改环境变量或可能禁止某些变量名称或值。因此,如果操作系统不允许修改,尝试修改映射可能会失败并出现 UnsupportedOperationException 或 IllegalArgumentException。
由于环境变量名称和值的外部格式取决于系统,因此它们与 Java 的 Unicode 字符串之间可能没有一对一的映射。尽管如此,映射的实现方式是,未由 Java 代码修改的环境变量将在子进程中具有未修改的本机表示。
返回的地图及其集合视图可能不遵守 Object#equals 和 Object#hashCode 方法的一般约定。
返回的地图通常在所有平台上都区分大小写。
如果存在安全管理器,则使用 RuntimePermission(“getenv.*”) 权限调用其 SecurityManager#checkPermission 方法。这可能会导致抛出 SecurityException。
将信息传递给 Java 子进程时,系统属性通常优于环境变量。
返回:
此流程构建器的环境
Throws:
Throw名称 | Throw描述 |
---|---|
SecurityException | 如果存在安全管理器并且其 SecurityManager#checkPermission 方法不允许访问进程环境 |
directory
public File directory()
返回此流程构建器的工作目录。 随后由该对象的 start() 方法启动的子进程将使用它作为其工作目录。 返回值可能为null——表示使用当前Java进程的工作目录,通常是系统属性user.dir命名的目录,作为子进程的工作目录。
返回:
此流程构建器的工作目录
directory
public ProcessBuilder directory(File directory)
设置此流程构建器的工作目录。 随后由该对象的 start() 方法启动的子进程将使用它作为其工作目录。 参数可以为null——表示使用当前Java进程的工作目录,通常是系统属性user.dir命名的目录,作为子进程的工作目录。
参数:
参数名称 | 参数描述 |
---|---|
directory | 新的工作目录 |
返回:
此流程构建器
redirectInput
public ProcessBuilder redirectInput(ProcessBuilder.Redirect source)
设置此流程构建器的标准输入源。 随后由该对象的 start() 方法启动的子进程从此源获取其标准输入。
如果源是 Redirect#PIPE(初始值),则可以使用 Process#getOutputStream() 返回的输出流写入子进程的标准输入。 如果源设置为任何其他值,则 Process#getOutputStream() 将返回一个空输出流。
参数:
参数名称 | 参数描述 |
---|---|
source | 新的标准输入源 |
返回:
此流程构建器
Throws:
Throw名称 | Throw描述 |
---|---|
IllegalArgumentException | 如果重定向不对应于有效的数据源,即类型为 WRITE 或 APPEND |
redirectOutput
public ProcessBuilder redirectOutput(ProcessBuilder.Redirect destination)
设置此流程构建器的标准输出目标。 随后由该对象的 start() 方法启动的子进程将其标准输出发送到该目的地。
如果目标是 Redirect#PIPE(初始值),则可以使用 Process#getInputStream() 返回的输入流读取子进程的标准输出。 如果目标设置为任何其他值,则 Process#getInputStream() 将返回一个空输入流。
参数:
参数名称 | 参数描述 |
---|---|
destination | 新的标准输出目的地 |
返回:
此流程构建器
Throws:
Throw名称 | Throw描述 |
---|---|
IllegalArgumentException | 如果重定向不对应于数据的有效目的地,即类型为 READ |
redirectError
public ProcessBuilder redirectError(ProcessBuilder.Redirect destination)
设置此流程构建器的标准错误目标。 随后由该对象的 start() 方法启动的子进程将其标准错误发送到该目的地。
如果目标是 Redirect#PIPE(初始值),则可以使用 Process#getErrorStream() 返回的输入流读取子进程的错误输出。 如果目标设置为任何其他值,则 Process#getErrorStream() 将返回空输入流。
如果redirectErrorStream 属性已设置为true,则此方法设置的重定向无效。
参数:
参数名称 | 参数描述 |
---|---|
destination | 新的标准错误目的地 |
返回:
此流程构建器
Throws:
Throw名称 | Throw描述 |
---|---|
IllegalArgumentException | 如果重定向不对应于数据的有效目的地,即类型为 READ |
redirectInput
public ProcessBuilder redirectInput(File file)
将此流程构建器的标准输入源设置为文件。
这是一种方便的方法。 形式redirectInput(file) 的调用与调用redirectInput (Redirect.from(file)) 的行为方式完全相同。
参数:
参数名称 | 参数描述 |
---|---|
file | 新的标准输入源 |
返回:
此流程构建器
redirectOutput
public ProcessBuilder redirectOutput(File file)
将此流程构建器的标准输出目标设置为文件。
这是一种方便的方法。 形式redirectOutput(file) 的调用与调用redirectOutput (Redirect.to(file)) 的行为方式完全相同。
参数:
参数名称 | 参数描述 |
---|---|
file | 新的标准输出目的地 |
返回:
此流程构建器
redirectError
public ProcessBuilder redirectError(File file)
将此流程构建器的标准错误目标设置为文件。
这是一种方便的方法。 调用redirectError(file) 形式的行为与调用redirectError (Redirect.to(file)) 完全相同。
参数:
参数名称 | 参数描述 |
---|---|
file | 新的标准错误目的地 |
返回:
此流程构建器
redirectInput
public ProcessBuilder.Redirect redirectInput()
返回此流程构建器的标准输入源。 随后由该对象的 start() 方法启动的子进程从此源获取其标准输入。 初始值为重定向#PIPE。
返回:
此流程构建器的标准输入源
redirectOutput
public ProcessBuilder.Redirect redirectOutput()
返回此流程构建器的标准输出目标。 随后由该对象的 start() 方法启动的子进程将其标准输出重定向到该目的地。 初始值为重定向#PIPE。
返回:
此流程构建器的标准输出目的地
redirectError
public ProcessBuilder.Redirect redirectError()
返回此流程构建器的标准错误目标。 随后由该对象的 start() 方法启动的子进程将其标准错误重定向到该目的地。 初始值为重定向#PIPE。
返回:
此流程构建器的标准错误目的地
inheritIO
public ProcessBuilder inheritIO()
将子进程标准 I/O 的源和目标设置为与当前 Java 进程的相同。
这是一种方便的方法。 表单的调用
pb.inheritIO()
行为方式与调用完全相同
pb.redirectInput(Redirect.INHERIT) .redirectOutput(Redirect.INHERIT) .redirectError(Redirect.INHERIT)
这提供了相当于大多数操作系统命令解释器或标准 C 库函数 system() 的行为。
返回:
此流程构建器
redirectErrorStream
public boolean redirectErrorStream()
告知此流程构建器是否合并标准错误和标准输出。
如果此属性为true,则随后由该对象的 start() 方法启动的子进程生成的任何错误输出都将与标准输出合并,以便可以使用 Process#getInputStream() 方法读取两者。 这使得更容易将错误消息与相应的输出相关联。 初始值为false。
返回:
此流程构建器的 redirectErrorStream 属性
redirectErrorStream
public ProcessBuilder redirectErrorStream(boolean redirectErrorStream)
设置此流程构建器的 redirectErrorStream 属性。
如果此属性为true,则随后由该对象的 start() 方法启动的子进程生成的任何错误输出都将与标准输出合并,以便可以使用 Process#getInputStream() 方法读取两者。 这使得更容易将错误消息与相应的输出相关联。 初始值为false。
参数:
参数名称 | 参数描述 |
---|---|
redirectErrorStream | 新的属性值 |
返回:
此流程构建器
start
public Process start() throws IOException
使用此流程构建器的属性启动一个新流程。
新进程将在由 directory() 给出的工作目录中调用由 command() 给出的命令和参数,以及由 environment() 给出的进程环境。
此方法检查该命令是否为有效的操作系统命令。哪些命令有效取决于系统,但至少该命令必须是非空字符串的非空列表。
在某些操作系统上启动进程可能需要一组最小的系统相关环境变量。因此,子流程可能会继承流程构建器的 environment() 之外的其他环境变量设置。
如果存在安全管理器,则调用其 SecurityManager#checkExec 方法,并使用此对象的命令数组的第一个组件作为其参数。这可能会导致抛出 SecurityException。
启动操作系统进程高度依赖于系统。可能出错的许多事情包括:
- 未找到操作系统程序文件。
- 访问程序文件被拒绝。
- 工作目录不存在。
在这种情况下会抛出异常。 异常的确切性质取决于系统,但它始终是 IOException 的子类。
对此流程构建器的后续修改不会影响返回的流程。
返回:
用于管理子流程的新流程对象
Throws:
Throw名称 | Throw描述 |
---|---|
NullPointerException | 如果命令列表的元素为空 |
IndexOutOfBoundsException | 如果命令是一个空列表(大小为 0) |
SecurityException | 如果存在安全管理器并且其 SecurityManager#checkExec 方法不允许创建子进程,或者子进程的标准输入从文件重定向并且安全管理器的 SecurityManager#checkRead 方法拒绝读取文件,或者标准输出或标准 子进程的错误被重定向到文件并且安全管理器的 SecurityManager#checkWrite 方法拒绝对文件的写访问 |
IOException | 如果发生 I/O 错误 |