从getInputStream正确关闭Java Process InputStream

Bob*_*Bob 27 java inputstream process

我在文档中找不到对此的澄清.但是当我们有一个Process物体并且打电话时getInputStream(),

当我们完成它时,我们是否会得到一个我们应该明确关闭的新流?或者我们是否得到了与流程相关的流,我们不应该关闭流程,但流程是否会关闭它?

基本上,我们应该如何与我们获得的流进行交互Process.getInputStream()?关闭还是不关闭?

Pet*_*aný 12

从阅读 UNIXProcess.java,这是发生了什么:

我们需要区分两种状态:要么进程还活着,要么已经死了。

如果进程处于活动状态,通过关闭 OutputStream(转到进程的标准输入),您告诉进程没有更多的输入。通过关闭 InputStreams(进程的 stdout、stderr),进程不再写入这些(如果尝试,它将获得 SIGPIPE)。

当进程终止时,Java 将缓冲来自 stdout/stderr 的剩余数据,并为您关闭所有三个流(它正在运行“进程收割者”线程,该线程在进程死亡时得到通知)。任何写入 OutputStream 的尝试都将失败。从 InputStream 读取将返回缓冲数据(如果有)。关闭它们中的任何一个都没有好处,但也不会造成任何伤害。(此时底层文件描述符已关闭)。


Ali*_*Ali 9

我的第一反应是关闭它,你总是关闭你打开的溪流.我确实认为文档不符合标准,但由于它们没有明确说明不要关闭对我来说意味着遵循良好的编程习惯.

InputStream is = process.getInputStream()
try {
    // your code
} finally {
    try { is.close(); } catch (Exception ignore) {}
}
Run Code Online (Sandbox Code Playgroud)

如果您需要确保这不成问题,只需编写一个快速测试用例,您可以在输入流中使用几十次,每次打开和关闭InputStream.

  • IOUtils.closeQuietly(is)将处理try {is.close(); } catch(异常忽略){} (4认同)

Roy*_*yce 5

当您调用时,Process.getInputStream()您将获得为该过程设置的现有输入流.当进程死亡,即输入流并没有离开自动-把它看成你仍然可以读取的缓冲区.管道的流程结束可能会关闭,但您的结束不是.关闭它是你的责任,尽管GC最终会得到它.

你还应该关闭另外两个:getErrorStream()getOutputStream().

  • “当进程终止时,该输入流不会自动消失”——当您启动一个进程时,Java 正在运行“进程收割者”线程,在这种情况下,它会关闭此类管道的本地端。 (2认同)