添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
此类用于创建操作系统进程。

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

可以调用 startPipeline 方法来创建新进程的管道,将每个进程的输出直接发送到下一个进程。每个流程都具有其各自 ProcessBuilder 的属性。

每个流程构建器管理这些流程属性:

  • a 命令 , 一个字符串列表,表示要调用的外部程序文件及其参数(如果有)。哪些字符串列表代表有效的操作系统命令是系统相关的。例如,每个概念参数通常都是此list中的一个元素,但在某些操作系统中,程序需要自己标记命令行字符串——在这样的系统上,Java 实现可能需要命令恰好包含两个元素。
  • 一个 环境 ,这是一个依赖于系统的映射 变量 values .初始值是当前进程环境的副本(参见 System.getenv() )。
  • a 工作目录 .默认值为当前进程的当前工作目录,通常是系统属性 user.dir 命名的目录。
  • a source of standard input 。默认情况下,子进程从管道读取输入。 Java 代码可以通过 Process.getOutputStream() 返回的输出流访问此管道。但是,可以使用 redirectInput 将标准输入重定向到另一个源。在这种情况下, Process.getOutputStream() 将返回一个 空输出流 ,其中:
  • write 方法总是抛出 IOException
  • close 方法什么都不做
  • a destination for standard output standard error 。默认情况下,子进程将标准输出和标准错误写入管道。 Java 代码可以通过 Process.getInputStream() Process.getErrorStream() 返回的输入流访问这些管道。但是,标准输出和标准错误可以使用 redirectOutput redirectError 重定向到其他目的地。在这种情况下, Process.getInputStream() 和/或 Process.getErrorStream() 将返回一个 空输入流 ,其中:
  • read 方法总是返回 -1
  • available 方法总是返回 0
  • close 方法什么都不做
  • a 重定向错误流 财产。最初,此属性为 false ,这意味着子进程的标准输出和错误输出被发送到两个单独的流,可以使用 Process.getInputStream() Process.getErrorStream() 方法访问它们。

    如果该值设置为 true ,则:

  • 标准错误与标准输出合并并始终发送到相同的目的地(这使得将错误消息与相应的输出相关联变得更容易)
  • 标准错误和标准输出的共同目的地可以使用 redirectOutput 重定向
  • 创建子进程时, redirectError 方法设置的任何重定向都将被忽略
  • Process.getErrorStream() 返回的流将始终是 空输入流
  • 修改进程构建器的属性将影响随后由该对象的 start() 方法启动的进程,但绝不会影响先前启动的进程或 Java 进程本身。

    大多数错误检查由 start() 方法执行。可以修改对象的状态,这样 start() 就会失败。例如,将命令属性设置为空列表不会引发异常,除非调用 start()

    Note that this class is not synchronized. 如果多个线程同时访问一个 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() ,然后再添加环境变量。

    除非另有说明,否则将 null 参数传递给此类中的构造函数或方法将导致抛出 NullPointerException

    返回此流程构建器环境的字符串映射视图。每当创建流程构建器时,环境都会初始化为当前流程环境的副本(请参阅 System.getenv() )。随后由该对象的 start() 方法启动的子进程将使用该map作为它们的环境。

    可以使用普通的 Map 操作修改返回的对象。这些修改将对通过 start() 方法启动的子进程可见。两个 ProcessBuilder 实例始终包含独立的进程环境,因此对返回映射的更改永远不会反映在任何其他 ProcessBuilder 实例或 System.getenv 返回的值中。

    如果系统不支持环境变量,则返回一个空map。

    返回的映射不允许空键或空值。尝试插入或查询空键或值的存在将抛出 NullPointerException 。尝试查询不属于 String 类型的键或值的存在将抛出 ClassCastException

    返回map的行为取决于系统。系统可能不允许修改环境变量或可能禁止某些变量名称或值。因此,如果操作系统不允许修改,尝试修改map可能会失败并返回 UnsupportedOperationException IllegalArgumentException

    由于环境变量名称和值的外部格式是系统相关的,因此它们与 Java 的 Unicode 字符串之间可能没有一对一的映射。尽管如此,映射的实现方式使得未被 Java 代码修改的环境变量将在子进程中具有未修改的本机表示。

    返回的map及其集合视图可能不遵守 Object.equals(java.lang.Object) Object.hashCode() 方法的一般约定。

    返回的map在所有平台上通常区分大小写。

    如果存在安全管理器,则使用 RuntimePermission ("getenv.*") 权限调用其 checkPermission 方法。这可能会导致抛出 SecurityException

    将信息传递给 Java 子进程时, 系统属性 通常优先于环境变量。

    这个过程构建器的环境
    SecurityException - 如果安全管理器存在且其 checkPermission 方法不允许访问进程环境
  • Runtime.exec(String[],String[],java.io.File)
  • System.getenv()
  • redirectOutput

    public ProcessBuilder redirectOutput ( ProcessBuilder.Redirect destination) 设置此流程构建器的标准输出目标。随后由该对象的 start() 方法启动的子进程将它们的标准输出发送到该目标。

    如果目标是 Redirect.PIPE (初始值),则可以使用 Process.getInputStream() 返回的输入流读取子进程的标准输出。如果目标设置为任何其他值,则 Process.getInputStream() 将返回 空输入流

    destination - 新的标准输出目的地 这个流程建设者
    IllegalArgumentException - 如果重定向不对应于有效的数据目的地,即类型为 READ

    redirectError

    public ProcessBuilder redirectError ( ProcessBuilder.Redirect destination) 设置此流程构建器的标准错误目标。随后由该对象的 start() 方法启动的子进程将它们的标准错误发送到该目的地。

    如果目标是 Redirect.PIPE (初始值),则可以使用 Process.getErrorStream() 返回的输入流读取子进程的错误输出。如果目标设置为任何其他值,则 Process.getErrorStream() 将返回 空输入流

    如果 redirectErrorStream 属性已设置 true ,则此方法设置的重定向无效。

    destination - 新的标准错误目的地 这个流程建设者
    IllegalArgumentException - 如果重定向不对应于有效的数据目的地,即类型为 READ pb.redirectInput(Redirect.INHERIT) .redirectOutput(Redirect.INHERIT) .redirectError(Redirect.INHERIT) 的行为完全相同,这给出的行为等同于大多数操作系统命令解释器或标准 C 库函数 system() 。 这个流程建设者

    redirectErrorStream

    public ProcessBuilder redirectErrorStream (boolean redirectErrorStream) 设置此流程构建器的 redirectErrorStream 属性。

    如果此属性为 true ,则此对象的 start() 方法随后启动的子进程生成的任何错误输出都将与标准输出合并,以便可以使用 Process.getInputStream() 方法读取两者。这使得将错误消息与相应的输出相关联变得更加容易。初始值为 false

    redirectErrorStream - 新属性值 这个流程建设者 使用此流程构建器的属性启动新流程。

    新进程将调用 command() 给出的命令和参数,在 directory() 给出的工作目录中,进程环境由 environment() 给出。

    此方法检查命令是否是有效的操作系统命令。哪些命令有效取决于系统,但至少命令必须是非空字符串的非空列表。

    在某些操作系统上启动进程可能需要一组最小的系统相关环境变量。因此,子流程可能会继承流程构建器的 environment() 之外的其他环境变量设置。

    如果存在安全管理器,则调用其 checkExec 方法,并将此对象的 command 数组的第一个组件作为其参数。这可能会导致抛出 SecurityException

    启动操作系统进程高度依赖于系统。许多可能出错的事情包括:

  • 找不到操作系统程序文件。
  • 访问程序文件被拒绝。
  • 工作目录不存在。
  • 命令参数中的字符无效,例如 NUL。
  • 在这种情况下,将抛出异常。异常的确切性质取决于系统,但它始终是 IOException 的子类。

    如果操作系统不支持创建进程,则会抛出一个 UnsupportedOperationException

    对此流程构建器的后续修改不会影响返回的 Process

    用于管理子进程的新 Process 对象
    NullPointerException - 如果命令列表的元素为空
    IndexOutOfBoundsException - 如果命令是空列表(大小为 0
    SecurityException - 如果存在安全管理器并且
  • 它的 checkExec 方法不允许创建子进程,或者
  • 子进程的标准输入是 从文件重定向 并且安全管理器的 checkRead 方法拒绝对该文件的读取访问,或者
  • 子进程的标准输出或标准错误为 重定向到一个文件 并且安全管理器的 checkWrite 方法拒绝对该文件的写访问
  • UnsupportedOperationException - 如果操作系统不支持创建进程。
    IOException - 如果发生 I/O 错误
  • Runtime.exec(String[], String[], java.io.File)
  • startPipeline

    public static List < Process > startPipeline ( List < ProcessBuilder > builders) throws IOException 为每个 ProcessBuilder 启动一个 Process,创建一个由其标准输出和标准输入流链接的流程管道。每个 ProcessBuilder 的属性都用于启动相应的进程,除了在启动每个进程时,其标准输出被定向到下一个进程的标准输入。第一个进程的标准输入和最后一个进程的标准输出的重定向使用相应 ProcessBuilder 的重定向设置进行初始化。所有其他 ProcessBuilder 重定向应该是 Redirect.PIPE

    中间进程之间的所有输入和输出流都是不可访问的。除第一个进程外的所有进程的 standard input 都是 空输出流 除最后一个进程外的所有进程的 standard output 都是 空输入流 .

    每个 ProcessBuilder 的 redirectErrorStream() 适用于各自的进程。如果设置为 true ,错误流将写入与标准输出相同的流。

    如果启动任何进程抛出异常,则所有进程都将被强制销毁。

    startPipeline 方法对每个 ProcessBuilder 执行与 start() 方法相同的检查。每个新进程调用相应进程构建器的 command() 给出的命令和参数,在其 directory() 给出的工作目录中,以及其 environment() 给出的进程环境。

    每个进程构建器的命令都被检查为有效的操作系统命令。哪些命令有效取决于系统,但至少命令必须是非空字符串的非空列表。

    在某些操作系统上启动进程可能需要一组最小的系统相关环境变量。因此,子流程可能会继承流程构建器的 environment() 之外的其他环境变量设置。

    如果有一个安全管理器,它的 checkExec 方法被调用,每个进程构建器的 command 数组的第一个组件作为它的参数。这可能会导致抛出 SecurityException

    启动操作系统进程高度依赖于系统。许多可能出错的事情包括:

  • 找不到操作系统程序文件。
  • 访问程序文件被拒绝。
  • 工作目录不存在。
  • 命令参数中的字符无效,例如 NUL。
  • 在这种情况下,将抛出异常。异常的确切性质取决于系统,但它始终是 IOException 的子类。

    如果操作系统不支持创建进程,则会抛出一个 UnsupportedOperationException

    对任何指定构建器的后续修改都不会影响返回的 Process

    API 注意: 例如,计算 Unix 兼容平台上文件层次结构中所有文件的唯一导入: String directory = "/home/duke/src"; ProcessBuilder[] builders = { new ProcessBuilder("find", directory, "-type", "f"), new ProcessBuilder("xargs", "grep", "-h", "^import "), new ProcessBuilder("awk", "{print $2;}"), new ProcessBuilder("sort", "-u")}; List<Process> processes = ProcessBuilder.startPipeline( Arrays.asList(builders)); Process last = processes.get(processes.size()-1); try (InputStream is = last.getInputStream(); Reader isr = new InputStreamReader(is); BufferedReader r = new BufferedReader(isr)) { long count = r.lines().count();
    builders - ProcessBuilder 列表
    List<Process> es 从对应的 ProcessBuilder 开始
    IllegalArgumentException - 除了第一个构建器的标准输入和最后一个构建器的标准输出之外的任何重定向都不是 ProcessBuilder.Redirect.PIPE
    NullPointerException - 如果命令列表的元素为空或者如果 ProcessBuilder 列表的元素为空或者构建器参数为空
    IndexOutOfBoundsException - 如果命令是空列表(大小为 0
    SecurityException - 如果存在安全管理器并且
  • 它的 checkExec 方法不允许创建子进程,或者
  • 子进程的标准输入是 从文件重定向 并且安全管理器的 checkRead 方法拒绝对该文件的读取访问,或者
  • 子进程的标准输出或标准错误为 重定向到一个文件 并且安全管理器的 checkWrite 方法拒绝对该文件的写访问
  • UnsupportedOperationException - 如果操作系统不支持创建进程
    IOException - 如果发生 I/O 错误 有关更多 API 参考和开发人文档,请参阅 Java SE 文档 ,其中包含更详细的、针对开发人的描述,以及概念概述、术语定义、解决方法和工作代码示例。 其他版本。
    Java 是 Oracle 和/或其附属公司在美国和其他国家/地区的商标或注册商标。
    版权 © 1993、2023,Oracle 和/或其附属公司,500 Oracle Parkway, Redwood Shores, CA 94065 USA。