模块 java.base
 java.lang

类 Process

java.lang.Object
java.lang.Process

public abstract class Process extends Object
Process 提供对由 ProcessBuilder.start 和 Runtime.exec 启动的本机进程的控制。该类提供了从进程执行输入、向进程执行输出、等待进程完成、检查进程退出状态和销毁(杀死)进程的方法。 ProcessBuilder.start() Runtime.exec 方法创建本机进程并返回 Process 的子类实例,可用于控制进程并获取有关它的信息。

创建进程的方法可能不适用于某些原生平台上的特殊进程,例如原生窗口进程、守护进程、Microsoft Windows 上的 Win16/DOS 进程或 shell 脚本。

默认情况下,创建的进程没有自己的终端或控制台。它的所有标准 I/O(即 stdin、stdout、stderr)操作将被重定向到父进程,在那里它们可以通过使用方法 getOutputStream() getInputStream() getErrorStream() 获得的流来访问。可以使用outputWriter() outputWriter(Charset) }、inputReader() inputReader(Charset) errorReader() errorReader(Charset) 方法写入和读取字符和行的I/O流。父进程使用这些流向进程提供输入并从中获取输出。由于一些原生平台只为标准输入输出流提供了有限的缓冲区大小,如果不能及时写入进程的输入流或读取输出流,可能会导致进程阻塞,甚至死锁。

在需要的地方,进程 I/O 也可以被重定向 使用 ProcessBuilder 类的方法。

当不再有对 Process 对象的引用时,进程不会被终止,而是进程继续异步执行。

Process 对象表示的进程相对于拥有 Process 对象的 Java 进程异步或并发执行是没有要求的。

从 1.5 开始,ProcessBuilder.start() 是创建 Process 的首选方法。

Process 的子类应重写 onExit() toHandle() 方法以提供功能齐全的 Process,包括 进程号有关过程的信息直系子女直系子女加上这些子女的后代 进程。委托给底层 Process 或 ProcessHandle 通常是最简单和最有效的。

自从:
1.0
  • 构造方法详细信息

    • Process

      public Process()
      Process 的默认构造方法。
  • 方法详情

    • getOutputStream

      public abstract OutputStream  getOutputStream()
      返回连接到进程正常输入的输出流。流的输出通过管道传输到此 Process 对象表示的进程的标准输入。

      如果进程的标准输入已使用 ProcessBuilder.redirectInput 重定向,则此方法将返回 空输出流

      API 注意:
      当同时写入 getOutputStream() outputWriter() outputWriter(Charset) 时,应在写入 OutputStream 之前调用 BufferedWriter.flush
      实现注意事项:
      实现注意事项:缓冲返回的输出流是个好主意。
      返回:
      连接到进程的正常输入的输出流
    • getInputStream

      public abstract InputStream  getInputStream()
      返回连接到进程正常输出的输入流。该流从该 Process 对象表示的进程的标准输出中获取数据。

      如果进程的标准输出已使用 ProcessBuilder.redirectOutput 重定向,则此方法将返回 空输入流

      否则,如果进程的标准错误已使用 ProcessBuilder.redirectErrorStream 重定向,则此方法返回的输入流将接收合并的标准输出和进程的标准错误。

      API 注意:
      请格外小心地使用 getInputStream() inputReader() BufferedReader 可能缓冲了来自输入流的输入。
      实现注意事项:
      实现说明:缓冲返回的输入流是个好主意。
      返回:
      输入流连接到进程的正常输出
    • getErrorStream

      public abstract InputStream  getErrorStream()
      返回连接到进程错误输出的输入流。该流从该 Process 对象表示的进程的错误输出中获取数据。

      如果进程的标准错误已使用 ProcessBuilder.redirectError ProcessBuilder.redirectErrorStream 重定向,则此方法将返回 空输入流

      API 注意:
      请格外小心地使用 getErrorStream() errorReader() BufferedReader 可能缓冲了来自错误流的输入。
      实现注意事项:
      实现说明:缓冲返回的输入流是个好主意。
      返回:
      输入流连接到进程的错误输出
    • inputReader

      public final BufferedReader  inputReader()
      返回连接到进程标准输出的 BufferedReader 。本机编码的 Charset 用于从标准输出读取字符、行或流线。

      此方法使用由 native.encoding 系统属性命名的 Charset 委托给 inputReader(Charset) 。如果 native.encoding 不是有效的字符集名称或不受支持,则使用 Charset.defaultCharset()

      返回:
      a BufferedReader 如果支持则使用 native.encoding,否则使用 Charset.defaultCharset()
      自从:
      17
    • inputReader

      public final BufferedReader  inputReader(Charset  charset)
      使用字符集返回连接到此进程的标准输出的 BufferedReader BufferedReader 可用于读取标准输出的字符、行或流线。

      字符由 InputStreamReader 读取并解码来自该进程 getInputStream() 的字节。使用 charset 将字节解码为字符;格式错误的输入和不可映射的字符序列被替换为字符集的默认替换。 BufferedReader 从 InputStreamReader 读取和缓冲字符。

      第一次调用此方法会创建 BufferedReader ,如果使用相同的 charset 再次调用,则返回相同的 BufferedReader。使用不同的 charset 再次调用此方法是错误的。

      如果进程的标准输出已使用 ProcessBuilder.redirectOutput 重定向,则 InputStreamReader 将从 空输入流 读取。

      否则,如果进程的标准错误已使用 ProcessBuilder.redirectErrorStream 重定向,则此方法返回的输入读取器将接收合并的标准输出和进程的标准错误。

      API 注意:
      同时使用 getInputStream() inputReader(Charset) 具有不可预知的行为,因为缓冲读取器会从输入流中提前读取。

      当进程终止并且标准输入没有被重定向时,从底层流读取可用字节是在尽力而为的基础上进行的,并且可能是不可预测的。

      参数:
      charset - Charset 用于将字节解码为字符
      返回:
      BufferedReader 用于使用 charset 的进程的标准输出
      抛出:
      NullPointerException - 如果 charsetnull
      IllegalStateException - 如果使用不同的字符集参数多次调用
      自从:
      17
    • errorReader

      public final BufferedReader  errorReader()
      返回一个连接到进程标准错误的BufferedReader 。本机编码的 Charset 用于从标准错误中读取字符、行或流线。

      此方法使用由 native.encoding 系统属性命名的 Charset 委托给 errorReader(Charset) 。如果 native.encoding 不是有效的字符集名称或不受支持,则使用 Charset.defaultCharset()

      返回:
      a BufferedReader 如果支持则使用 native.encoding,否则使用 Charset.defaultCharset()
      自从:
      17
    • errorReader

      public final BufferedReader  errorReader(Charset  charset)
      使用字符集返回连接到此进程的标准错误的 BufferedReader BufferedReader 可用于读取标准错误的字符、行或流线。

      字符由 InputStreamReader 读取并解码来自该进程 getErrorStream() 的字节。使用 charset 将字节解码为字符;格式错误的输入和不可映射的字符序列被替换为字符集的默认替换。 BufferedReader 从 InputStreamReader 读取和缓冲字符。

      第一次调用此方法会创建 BufferedReader ,如果使用相同的 charset 再次调用,则返回相同的 BufferedReader。使用不同的 charset 再次调用此方法是错误的。

      如果进程的标准错误已使用 ProcessBuilder.redirectError ProcessBuilder.redirectErrorStream 重定向,则 InputStreamReader 将从 空输入流 读取。

      API 注意:
      同时使用 getErrorStream() errorReader(Charset) 具有不可预测的行为,因为缓冲读取器会从错误流中提前读取。

      当进程终止并且标准错误没有被重定向时,从底层流中读取可用字节是在尽力而为的基础上,并且可能是不可预测的。

      参数:
      charset - Charset 用于将字节解码为字符
      返回:
      BufferedReader 用于使用 charset 的过程的标准错误
      抛出:
      NullPointerException - 如果 charsetnull
      IllegalStateException - 如果使用不同的字符集参数多次调用
      自从:
      17
    • outputWriter

      public final BufferedWriter  outputWriter()
      返回一个 BufferedWriter 连接到使用本机编码的进程的正常输入。将文本写入字符输出流,缓冲字符,以便高效地写入单个字符、数组和字符串。

      此方法使用由 native.encoding 系统属性命名的 Charset 委托给 outputWriter(Charset) 。如果 native.encoding 不是有效的字符集名称或不受支持,则使用 Charset.defaultCharset()

      返回:
      a BufferedWriter 到使用 native.encoding 系统属性的字符集的进程的标准输入
      自从:
      17
    • outputWriter

      public final BufferedWriter  outputWriter(Charset  charset)
      返回一个 BufferedWriter 连接到使用字符集的进程的正常输入。将文本写入字符输出流,缓冲字符,以便高效地写入单个字符、数组和字符串。

      作者写入的字符使用 OutputStreamWriter 编码为字节,而 Charset 被写入此 Process 表示的进程的标准输入。格式错误的输入和不可映射的字符序列被替换为字符集的默认替换。

      第一次调用此方法会创建 BufferedWriter ,如果使用相同的 charset 再次调用,则返回相同的 BufferedWriter 。使用不同的 charset 再次调用此方法是错误的。

      如果进程的标准输入已使用 ProcessBuilder.redirectInput 重定向,则 OutputStreamWriter 将写入 空输出流

      API 注意:
      BufferedWriter 写入字符、字符数组和字符串。用 PrintWriter 包装 BufferedWriter 提供有效的缓冲和格式化基元和对象,以及支持自动刷新行尾。调用 BufferedWriter.flush() 方法将缓冲输出刷新到进程。

      当同时写入 getOutputStream() outputWriter() outputWriter(Charset) 时,应在写入 OutputStream 之前调用 BufferedWriter.flush

      参数:
      charset - Charset 将字符编码为字节
      返回:
      BufferedWriter 到使用 charset 的进程的标准输入
      抛出:
      NullPointerException - 如果 charsetnull
      IllegalStateException - 如果使用不同的字符集参数多次调用
      自从:
      17
    • waitFor

      public abstract int waitFor() throws InterruptedException
      如有必要,使当前线程等待,直到此 Process 对象表示的进程终止。如果进程已经终止,则此方法立即返回。如果进程尚未终止,则调用线程将被阻塞,直到进程退出。
      返回:
      Process 对象表示的进程的退出值。按照惯例,值0 表示正常终止。
      抛出:
      InterruptedException - 如果当前线程在等待时被另一个线程interrupted,则等待结束并抛出InterruptedException
    • waitFor

      public boolean waitFor(long timeout, TimeUnit  unit) throws InterruptedException
      如有必要,使当前线程等待,直到此 Process 对象表示的进程终止,或指定的等待时间结束。

      如果进程已经终止,则此方法立即返回值 true 。如果进程尚未终止且超时值小于或等于零,则此方法立即返回值 false

      此方法的默认实现轮询 exitValue 以检查进程是否已终止。强烈建议此类的具体实现使用更有效的实现来覆盖此方法。

      参数:
      timeout - 最长时间等待
      unit - timeout 参数的时间单位
      返回:
      true 如果进程已退出, false 如果在进程退出之前等待时间已过。
      抛出:
      InterruptedException - 如果当前线程在等待时被中断。
      NullPointerException - 如果单位为空
      自从:
      1.8
    • exitValue

      public abstract int exitValue()
      返回进程的退出值。
      返回:
      Process 对象表示的进程的退出值。按照惯例,值0 表示正常终止。
      抛出:
      IllegalThreadStateException - 如果此 Process 对象表示的进程尚未终止
    • destroy

      public abstract void destroy()
      杀死进程。此 Process 对象表示的进程是否为 正常终止 取决于实现。强制进程销毁定义为进程的立即终止,而正常终止允许进程干净地关闭。如果进程不活动,则不采取任何操作。

      当进程终止时,来自 onExit() CompletableFuture completed

    • destroyForcibly

      public Process  destroyForcibly()
      强行杀死进程。此 Process 对象表示的进程被强制终止。强制进程销毁定义为进程的立即终止,而正常终止允许进程干净地关闭。如果进程不活动,则不采取任何操作。

      当进程终止时,来自 onExit() CompletableFuture completed

      ProcessBuilder.start() Runtime.exec(java.lang.String) 返回的 Process 对象上调用此方法强制终止进程。

      API 注意:
      该过程可能不会立即终止。即 isAlive() 可能会在调用 destroyForcibly() 后的短时间内返回 true。如果需要,可以将此方法链接到 waitFor()
      实现要求:
      此方法的默认实现调用 destroy() ,因此可能不会强制终止进程。
      实现注意事项:
      强烈建议此类的具体实现使用兼容的实现重写此方法。
      返回:
      代表进程被强行销毁的Process对象
      自从:
      1.8
    • supportsNormalTermination

      public boolean supportsNormalTermination()
      如果destroy() 的执行是正常终止进程则返回true,如果destroy的执行强制立即终止进程则返回false

      ProcessBuilder.start() Runtime.exec(java.lang.String) 返回的 Process 对象上调用此方法返回 truefalse,具体取决于平台实现。

      实现要求:
      此实现抛出 UnsupportedOperationException 的实例并且不执行任何其他操作。
      返回:
      true如果执行destroy() 是为了正常终止进程;否则,destroy() 强行终止进程
      抛出:
      UnsupportedOperationException - 如果 Process 实现不支持此操作
      自从:
      9
    • isAlive

      public boolean isAlive()
      测试这个 Process 代表的进程是否存活。
      返回:
      true 如果此 Process 对象表示的进程尚未终止。
      自从:
      1.8
    • pid

      public long pid()
      返回进程的本机进程 ID。本机进程 ID 是操作系统分配给进程的标识号。
      实现要求:
      此方法的实现返回进程 ID 为:toHandle().pid()
      返回:
      进程的本机进程 ID
      抛出:
      UnsupportedOperationException - 如果 Process 实现不支持此操作
      自从:
      9
    • onExit

      public CompletableFuture <Process > onExit()
      返回一个 CompletableFuture<Process> 以终止进程。 CompletableFuture 提供触发依赖函数或操作的能力,这些函数或操作可以在进程终止时同步或异步运行。当进程终止时,无论进程的退出状态如何,CompletableFuture 都是completed

      调用onExit().get()等待进程终止并返回进程。未来可用于检查进程是否为 donewait 以使其终止。 取消 CompletableFuture 不影响 Process。

      ProcessBuilder.start() 返回的进程覆盖默认实现以提供等待进程退出的有效机制。

      API 注意:
      使用 onExit waitFor 的替代方法,它既可以实现额外的并发性,又可以方便地访问流程的结果。 Lambda 表达式可用于评估流程执行的结果。如果在使用该值之前还有其他处理要完成,那么 onExit 是一种方便的机制,可以释放当前线程并仅在需要该值时才阻塞。
      例如,启动一个进程来比较两个文件并在它们相同时获取boolean:
        Process p = new ProcessBuilder("cmp", "f1", "f2").start();
        Future<Boolean> identical = p.onExit().thenApply(p1 -> p1.exitValue() == 0);
        ...
        if (identical.get()) { ... }
        
      ,在 ComputableFuture 完成并调用相关操作之前,可以观察到该进程已终止并返回 isAlive()
      实现要求:
      此实现在单独的线程中重复执行 waitFor() ,直到成功返回。如果 waitFor 的执行被中断,线程的中断状态将被保留。

      waitFor() 成功返回时,CompletableFuture 为 completed 而不管进程的退出状态如何。如果并发等待大量进程,此实现可能会消耗大量线程堆栈内存。

      外部实现应该重写此方法并提供更有效的实现。例如,要委托给底层进程,它可以执行以下操作:

      
        public CompletableFuture<Process> onExit() {
          return delegate.onExit().thenApply(p -> this);
        }
        
      返回:
      一个新的 CompletableFuture<Process> 用于进程
      自从:
      9
    • toHandle

      public ProcessHandle  toHandle()
      返回进程的 ProcessHandle。 ProcessBuilder.start() Runtime.exec(java.lang.String) 返回的 Process 对象将 toHandle 实现为 ProcessHandle.of(pid) 的等价物,包括对 SecurityManager 和 RuntimePermission("manageProcess") 的检查。
      实现要求:
      此实现抛出 UnsupportedOperationException 的实例并且不执行任何其他操作。子类应该覆盖此方法以为进程提供 ProcessHandle。方法 pid() info() children() descendants() 除非被覆盖,否则对 ProcessHandle 进行操作。
      返回:
      返回进程的 ProcessHandle
      抛出:
      UnsupportedOperationException - 如果 Process 实现不支持此操作
      SecurityException - 如果安装了安全管理器并且它拒绝 RuntimePermission("manageProcess")
      自从:
      9
    • info

      public ProcessHandle.Info  info()
      返回有关进程的信息快照。

      ProcessHandle.Info 实例具有访问器方法,如果可用则返回有关进程的信息。

      实现要求:
      此实现将有关进程的信息返回为:toHandle().info()
      返回:
      有关进程的信息快照,始终为非空
      抛出:
      UnsupportedOperationException - 如果 Process 实现不支持此操作
      自从:
      9
    • children

      public Stream <ProcessHandle > children()
      返回进程的直接子进程的快照。直接子进程的父进程是进程。通常,没活着 进程没有子进程。

      Note that processes are created and terminate asynchronously. There is no guarantee that a process is alive.

      实现要求:
      此实现将直接子级返回为:toHandle().children()
      返回:
      ProcessHandles 的顺序 Stream,用于作为进程的直接子进程的进程
      抛出:
      UnsupportedOperationException - 如果 Process 实现不支持此操作
      SecurityException - 如果安装了安全管理器并且它拒绝 RuntimePermission("manageProcess")
      自从:
      9
    • descendants

      public Stream <ProcessHandle > descendants()
      返回进程后代的快照。进程的后代是进程的子代加上这些子代的后代,递归地。通常,没活着 进程没有子进程。

      Note that processes are created and terminate asynchronously. There is no guarantee that a process is alive.

      实现要求:
      此实现将所有子项返回为:toHandle().descendants()
      返回:
      ProcessHandles 的顺序 Stream,用于作为进程后代的进程
      抛出:
      UnsupportedOperationException - 如果 Process 实现不支持此操作
      SecurityException - 如果安装了安全管理器并且它拒绝 RuntimePermission("manageProcess")
      自从:
      9