阅读(4680) (0)

鸿蒙OS ProcessBuilder

2022-04-28 15:59:35 更新

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