【问题标题】:Properly closing Java Process InputStream from getInputStream从 getInputStream 正确关闭 Java Process InputStream
【发布时间】:2011-10-29 04:31:03
【问题描述】:

我无法在文档中找到对此的说明。 但是当我们有一个Process 对象并调用getInputStream() 时,

我们是否得到了一个新的流,我们应该在完成后明确关闭它? 要么 我们是否获得了与 Process 相关联的已经存在的流,我们不应该关闭它,但 Process 会负责关闭它?

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

【问题讨论】:

    标签: java process inputstream


    【解决方案1】:

    通过阅读 UNIXProcess.java,会发生以下情况:

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

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

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

    【讨论】:

    • 你能备份一下吗?这是一个有趣的主题,你的回答有细节。谢谢。
    • 关闭 InputStream 是否肯定会清除缓冲区?即如果进程已死,但缓冲区中有未读数据,是否在关闭 InputStream 时肯定会从缓冲区中删除?
    【解决方案2】:

    我的第一反应是关闭它,你总是关闭你打开的流。我确实意识到文档没有达到标准,但由于他们没有明确声明不要关闭,这对我来说意味着遵循良好的编程实践。

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

    如果您需要确保这没有问题,只需编写一个快速测试用例,您可以从输入流中多次打开和关闭 InputStream。

    【讨论】:

    • IOUtils.closeQuietly(is) 将处理 try { is.close(); } 捕捉(异常忽略){}
    【解决方案3】:

    当您调用Process.getInputStream() 时,您会得到一个为进程设置的现有输入流。当进程终止时,输入流不会自动消失 - 将其视为您仍然可以从中读取的缓冲区。进程的管道末端可能已关闭,但您的末端不是。关闭它是你的责任,尽管 GC 最终会得到它。

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

    【讨论】:

    • “当进程终止时,输入流不会自动消失”——当你启动一个进程时,Java 正在运行“进程收割机”线程,它会在此关闭此类管道的本地端案例。
    【解决方案4】:

    你没有关闭流,你没有打开 - 这是一个令人讨厌的副作用。 如果您创建了该进程,请先将其终止,然后再关闭流。

    【讨论】:

      【解决方案5】:

      我总是关闭它们!我不是 100% 确定,但据我所知,如果您打开输入流,文件将一直打开,直到您关闭它!所以遵循“标准规则”并关闭它!举个例子: Process Builder waitFor() issue and Open file limitations

      【讨论】:

        猜你喜欢
        • 2020-03-20
        • 2018-05-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多