Module  java.base
软件包  java.lang

Class ProcessBuilder



  • public final class ProcessBuilder
    extends Object
    此类用于创建操作系统进程。

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

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

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

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

      如果该值设置为true ,则:

      • 标准错误与标准输出合并,并始终发送到同一目的地(这使得更容易将错误消息与相应的输出相关联)
      • 标准错误和标准输出的公共目的地可以使用redirectOutput重定向
      • 在创建子进程时,将忽略redirectError方法设置的任何重定向
      • Process.getErrorStream()返回的流将始终是一个null input stream

    修改流程构建器的属性将影响随后由该对象的start()方法启动的进程,但不会影响以前启动的进程或Java进程本身。

    大多数错误检查由start()方法执行。 可以修改对象的状态,使start()失败。 例如,将命令属性设置为空列表将不会抛出异常,除非调用了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()

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

    从以下版本开始:
    1.5
    • 构造方法详细信息

      • ProcessBuilder

        public ProcessBuilder​(List<String> command)
        构造具有指定操作系统程序和参数的进程构建器。 此构造不会使副本command列表。 列表的后续更新将反映在流程构建器的状态。 不检查command是否对应于有效的操作系统命令。
        参数
        command - 包含程序及其参数的列表
      • ProcessBuilder

        public ProcessBuilder​(String... command)
        构造具有指定操作系统程序和参数的进程构建器。 这是一个方便的构造函数,它以相同的顺序将流程构建器的命令设置为包含与command数组相同的字符串的字符串列表。 不检查command是否对应于有效的操作系统命令。
        参数
        command - 包含程序及其参数的字符串数组
    • 方法详细信息

      • command

        public ProcessBuilder command​(List<String> command)
        设置此流程构建器的操作系统程序和参数。 这种方法不会使副本command列表。 列表的后续更新将反映在流程构建器的状态。 不检查command是否对应于有效的操作系统命令。
        参数
        command - 包含程序及其参数的列表
        结果
        这个流程生成器
      • command

        public ProcessBuilder command​(String... command)
        设置此流程构建器的操作系统程序和参数。 这是一个方便的方法,将命令设置为包含与command数组相同的字符串的字符串列表,顺序相同。 不检查command是否对应于有效的操作系统命令。
        参数
        command - 包含程序及其参数的字符串数组
        结果
        这个流程生成器
      • command

        public List<String> command​()
        返回此流程构建器的操作系统程序和参数。 返回的列表不是副本。 列表的后续更新将反映在此流程构建器的状态中。
        结果
        这个流程制造商的计划及其论据
      • environment

        public Map<String,String> environment​()
        返回此流程构建器环境的字符串映射视图。 无论何时创建流程构建器,环境都将初始化为当前进程环境的副本(请参阅System.getenv() )。 随后由该对象的start()方法开始的处理将使用此映射作为其环境。

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

        如果系统不支持环境变量,则返回空的地图。

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

        返回地图的行为依赖于系统。 系统可能不允许修改环境变量或禁止某些变量名称或值。 因此,如果操作系统不允许修改,则尝试修改映射可能会因为UnsupportedOperationExceptionIllegalArgumentException而失败。

        由于环境变量名称和值的外部格式与系统相关,因此可能与Java的Unicode字符串之间不存在一对一的映射。 然而,地图的实现方式是,未被Java代码修改的环境变量将在子进程中具有未修改的本地表示。

        返回的地图及其收藏意见可能不符合Object.equals(java.lang.Object)Object.hashCode()方法的一般合同。

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

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

        将信息传递给Java子进程时 ,通常比环境变量更喜欢system properties

        结果
        这个过程建设者的环境
        异常
        SecurityException - 如果存在安全管理员,并且其 checkPermission方法不允许访问进程环境
        另请参见:
        Runtime.exec(String[],String[],java.io.File)System.getenv()
      • 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​(File file)
        将此流程构建器的标准输入源设置为文件。

        这是一种方便的方法。 调用表单redirectInput(file)行为方式与调用redirectInput (Redirect.from(file))

        参数
        file - 新的标准输入源
        结果
        这个流程生成器
        从以下版本开始:
        1.7
      • redirectOutput

        public ProcessBuilder redirectOutput​(File file)
        将此流程构建器的标准输出目标设置为文件。

        这是一种方便的方法。 表单redirectOutput(file)的调用与调用redirectOutput (Redirect.to(file))

        参数
        file - 新的标准输出目的地
        结果
        这个流程生成器
        从以下版本开始:
        1.7
      • redirectError

        public ProcessBuilder redirectError​(File file)
        将此流程构建器的标准错误目标设置为文件。

        这是一种方便的方法。 调用表单redirectError(file)行为方式与调用redirectError (Redirect.to(file))

        参数
        file - 新的标准错误目的地
        结果
        这个流程生成器
        从以下版本开始:
        1.7
      • redirectInput

        public ProcessBuilder.Redirect redirectInput​()
        返回此流程构建器的标准输入源。 子进程随后由该对象的start()方法启动,从该源获取其标准输入。 初始值为Redirect.PIPE
        结果
        这个流程制造商的标准输入源
        从以下版本开始:
        1.7
      • redirectOutput

        public ProcessBuilder.Redirect redirectOutput​()
        返回此流程构建器的标准输出目标。 子进程随后由该对象的start()方法启动,将其标准输出重定向到此目标。 初始值为Redirect.PIPE
        结果
        该流程制造商的标准输出目的地
        从以下版本开始:
        1.7
      • redirectError

        public ProcessBuilder.Redirect redirectError​()
        返回此流程构建器的标准错误目标。 子进程随后由该对象的start()方法启动,将其标准错误重定向到此目标。 初始值为Redirect.PIPE
        结果
        此流程构建器的标准错误目标
        从以下版本开始:
        1.7
      • inheritIO

        public ProcessBuilder inheritIO​()
        将子进程标准I / O的源和目标设置为与当前Java进程相同。

        这是一种方便的方法。 调用表单

           pb.inheritIO()  
        行为与调用完全相同
           pb.redirectInput(Redirect.INHERIT) .redirectOutput(Redirect.INHERIT) .redirectError(Redirect.INHERIT)  
        这给出了与大多数操作系统命令解释器相同的行为,或标准C库函数system()
        结果
        这个流程生成器
        从以下版本开始:
        1.7
      • 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
        使用此流程构建器的属性启动新进程。

        新进程将调用由指定的命令和参数command()按以下给出,在工作目录directory() ,有一个过程的环境被给出environment()

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

        在某些操作系统上启动一个进程可能需要一小部分与系统相关的环境变量。 因此,子进程可能会继承其他环境变量设置,而不是进程生成器的environment()

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

        启动操作系统进程与系统相关。 许多可能出错的事情是:

        • 找不到操作系统程序文件。
        • 对程序文件的访问被拒绝。
        • 工作目录不存在。
        • 命令参数中的字符无效,如NUL。

        在这种情况下,会抛出异常。 异常的确切性质是系统依赖的,但它始终是IOException的子类。

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

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

        结果
        一个用于管理子进程的新的Process对象
        异常
        NullPointerException - 如果命令列表的元素为空
        IndexOutOfBoundsException - 如果命令是空列表(具有大小 0
        SecurityException - 如果存在安全管理员,
        UnsupportedOperationException - 如果操作系统不支持创建进程。
        IOException - 如果发生I / O错误
        另请参见:
        Runtime.exec(String[], String[], java.io.File)
      • startPipeline

        public static List<Process> startPipeline​(List<ProcessBuilder> builders)
                                           throws IOException
        为每个ProcessBuilder启动流程,创建一个由其标准输出流和标准输入流链接的流程。 每个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 Note:
        例如,要计算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 - ProcessBuilders列表
        结果
        一个 List<Process>从相应的ProcessBuilder开始
        异常
        IllegalArgumentException - 除了第一个构建器的标准输入和最后一个构建器的标准输出之外的任何重定向不是 ProcessBuilder.Redirect.PIPE
        NullPointerException - 如果命令列表的元素为空,或者ProcessBuilder列表的元素为空或者构建器参数为空
        IndexOutOfBoundsException - 如果命令是空列表(具有大小 0
        SecurityException - 如果存在安全管理员,
        UnsupportedOperationException - 如果操作系统不支持创建进程
        IOException - 如果发生I / O错误
        从以下版本开始:
        9