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
-
构造方法总结
构造方法 -
方法总结
修饰符和类型方法描述children()返回进程的直接子进程的快照。返回进程后代的快照。abstract voiddestroy()杀死进程。强行杀死进程。final BufferedReader返回一个连接到进程标准错误的BufferedReader。final BufferedReadererrorReader(Charset charset) 使用字符集返回连接到此进程的标准错误的BufferedReader。abstract int返回进程的退出值。abstract InputStream返回连接到进程错误输出的输入流。abstract InputStream返回连接到进程正常输出的输入流。abstract OutputStream返回连接到进程正常输入的输出流。info()返回有关进程的信息快照。final BufferedReader返回连接到进程标准输出的BufferedReader。final BufferedReaderinputReader(Charset charset) 使用字符集返回连接到此进程的标准输出的BufferedReader。booleanisAlive()测试这个Process代表的进程是否存活。onExit()返回一个CompletableFuture<Process>以终止进程。final BufferedWriter返回一个BufferedWriter连接到使用本机编码的进程的正常输入。final BufferedWriteroutputWriter(Charset charset) 返回一个BufferedWriter连接到使用字符集的进程的正常输入。longpid()返回进程的本机进程 ID。booleantoHandle()返回进程的 ProcessHandle。abstract intwaitFor()如有必要,使当前线程等待,直到此Process对象表示的进程终止。boolean如有必要,使当前线程等待,直到此Process对象表示的进程终止,或指定的等待时间结束。
-
构造方法详细信息
-
Process
public Process()Process 的默认构造方法。
-
-
方法详情
-
getOutputStream
返回连接到进程正常输入的输出流。流的输出通过管道传输到此Process对象表示的进程的标准输入。如果进程的标准输入已使用
ProcessBuilder.redirectInput重定向,则此方法将返回 空输出流 。- API 注意:
-
当同时写入
getOutputStream()和outputWriter()或outputWriter(Charset)时,应在写入OutputStream之前调用BufferedWriter.flush。 - 实现注意事项:
- 实现注意事项:缓冲返回的输出流是个好主意。
- 返回:
- 连接到进程的正常输入的输出流
-
getInputStream
返回连接到进程正常输出的输入流。该流从该Process对象表示的进程的标准输出中获取数据。如果进程的标准输出已使用
ProcessBuilder.redirectOutput重定向,则此方法将返回 空输入流 。否则,如果进程的标准错误已使用
ProcessBuilder.redirectErrorStream重定向,则此方法返回的输入流将接收合并的标准输出和进程的标准错误。- API 注意:
-
请格外小心地使用
getInputStream()和inputReader()。BufferedReader可能缓冲了来自输入流的输入。 - 实现注意事项:
- 实现说明:缓冲返回的输入流是个好主意。
- 返回:
- 输入流连接到进程的正常输出
-
getErrorStream
返回连接到进程错误输出的输入流。该流从该Process对象表示的进程的错误输出中获取数据。如果进程的标准错误已使用
ProcessBuilder.redirectError或ProcessBuilder.redirectErrorStream重定向,则此方法将返回 空输入流 。- API 注意:
-
请格外小心地使用
getErrorStream()和errorReader()。BufferedReader可能缓冲了来自错误流的输入。 - 实现注意事项:
- 实现说明:缓冲返回的输入流是个好主意。
- 返回:
- 输入流连接到进程的错误输出
-
inputReader
返回连接到进程标准输出的BufferedReader。本机编码的Charset用于从标准输出读取字符、行或流线。此方法使用由
native.encoding系统属性命名的Charset委托给inputReader(Charset)。如果native.encoding不是有效的字符集名称或不受支持,则使用Charset.defaultCharset()。- 返回:
-
a
BufferedReader如果支持则使用native.encoding,否则使用Charset.defaultCharset() - 自从:
- 17
-
inputReader
使用字符集返回连接到此进程的标准输出的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- 如果charset是nullIllegalStateException- 如果使用不同的字符集参数多次调用- 自从:
- 17
-
errorReader
返回一个连接到进程标准错误的BufferedReader。本机编码的Charset用于从标准错误中读取字符、行或流线。此方法使用由
native.encoding系统属性命名的Charset委托给errorReader(Charset)。如果native.encoding不是有效的字符集名称或不受支持,则使用Charset.defaultCharset()。- 返回:
-
a
BufferedReader如果支持则使用native.encoding,否则使用Charset.defaultCharset() - 自从:
- 17
-
errorReader
使用字符集返回连接到此进程的标准错误的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- 如果charset是nullIllegalStateException- 如果使用不同的字符集参数多次调用- 自从:
- 17
-
outputWriter
返回一个BufferedWriter连接到使用本机编码的进程的正常输入。将文本写入字符输出流,缓冲字符,以便高效地写入单个字符、数组和字符串。此方法使用由
native.encoding系统属性命名的Charset委托给outputWriter(Charset)。如果native.encoding不是有效的字符集名称或不受支持,则使用Charset.defaultCharset()。- 返回:
-
a
BufferedWriter到使用native.encoding系统属性的字符集的进程的标准输入 - 自从:
- 17
-
outputWriter
返回一个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- 如果charset是nullIllegalStateException- 如果使用不同的字符集参数多次调用- 自从:
- 17
-
waitFor
如有必要,使当前线程等待,直到此Process对象表示的进程终止。如果进程已经终止,则此方法立即返回。如果进程尚未终止,则调用线程将被阻塞,直到进程退出。- 返回:
-
此
Process对象表示的进程的退出值。按照惯例,值0表示正常终止。 - 抛出:
InterruptedException- 如果当前线程在等待时被另一个线程interrupted,则等待结束并抛出InterruptedException。
-
waitFor
如有必要,使当前线程等待,直到此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
强行杀死进程。此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对象上调用此方法返回true或false,具体取决于平台实现。- 实现要求:
-
此实现抛出
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
返回一个CompletableFuture<Process>以终止进程。CompletableFuture提供触发依赖函数或操作的能力,这些函数或操作可以在进程终止时同步或异步运行。当进程终止时,无论进程的退出状态如何,CompletableFuture 都是completed。调用
onExit().get()等待进程终止并返回进程。未来可用于检查进程是否为 done 或 wait 以使其终止。 取消 CompletableFuture 不影响 Process。从
ProcessBuilder.start()返回的进程覆盖默认实现以提供等待进程退出的有效机制。- API 注意:
-
使用
onExit是waitFor的替代方法,它既可以实现额外的并发性,又可以方便地访问流程的结果。 Lambda 表达式可用于评估流程执行的结果。如果在使用该值之前还有其他处理要完成,那么 onExit 是一种方便的机制,可以释放当前线程并仅在需要该值时才阻塞。
例如,启动一个进程来比较两个文件并在它们相同时获取boolean:
,在 ComputableFuture 完成并调用相关操作之前,可以观察到该进程已终止并返回Process p = new ProcessBuilder("cmp", "f1", "f2").start(); Future<Boolean> identical = p.onExit().thenApply(p1 -> p1.exitValue() == 0); ... if (identical.get()) { ... }isAlive()。 - 实现要求:
-
此实现在单独的线程中重复执行
waitFor(),直到成功返回。如果waitFor的执行被中断,线程的中断状态将被保留。当
waitFor()成功返回时,CompletableFuture 为 completed 而不管进程的退出状态如何。如果并发等待大量进程,此实现可能会消耗大量线程堆栈内存。外部实现应该重写此方法并提供更有效的实现。例如,要委托给底层进程,它可以执行以下操作:
public CompletableFuture<Process> onExit() { return delegate.onExit().thenApply(p -> this); } - 返回:
-
一个新的
CompletableFuture<Process>用于进程 - 自从:
- 9
-
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
返回有关进程的信息快照。ProcessHandle.Info实例具有访问器方法,如果可用则返回有关进程的信息。- 实现要求:
-
此实现将有关进程的信息返回为:
toHandle().info()。 - 返回:
- 有关进程的信息快照,始终为非空
- 抛出:
UnsupportedOperationException- 如果 Process 实现不支持此操作- 自从:
- 9
-
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
返回进程后代的快照。进程的后代是进程的子代加上这些子代的后代,递归地。通常,没活着 进程没有子进程。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
-