如何适当地从 java.lang.Process 关闭 std-streams?

2023-12-02

这个问题是关于java.lang.Process及其对 stdin、stdout 和 stderr 的处理。

我们的项目中有一个类是对org.apache.commons.io.IOUtils。我们有一个安静的新方法来关闭进程对象的标准流吗?还是不合适?

/**
 * Method closes all underlying streams from the given Process object.
 * If Exit-Code is not equal to 0 then Process will be destroyed after 
 * closing the streams.
 *
 * It is guaranteed that everything possible is done to release resources
 * even when Throwables are thrown in between.
 *
 * In case of occurances of multiple Throwables then the first occured
 * Throwable will be thrown as Error, RuntimeException or (masked) IOException.
 *
 * The method is null-safe.
 */
public static void close(@Nullable Process process) throws IOException {
    if(process == null) {
      return;
    }

    Throwable t = null;

    try {
      close(process.getOutputStream());
    }
    catch(Throwable e) {
      t = e;
    }

    try{
      close(process.getInputStream());
    }
    catch(Throwable e) {
      t = (t == null) ? e : t;
    }

    try{
      close(process.getErrorStream());
    }
    catch (Throwable e) {
      t = (t == null) ? e : t;
    }

    try{
      try {
        if(process.waitFor() != 0){
          process.destroy();
        }
      }
      catch(InterruptedException e) {
        t = (t == null) ? e : t;
        process.destroy();
      }
    }
    catch (Throwable e) {
      t = (t == null) ? e : t;
    }

    if(t != null) {
      if(t instanceof Error) {
        throw (Error) t;
      }

      if(t instanceof RuntimeException) {
        throw (RuntimeException) t;
      }

      throw t instanceof IOException ? (IOException) t : new IOException(t);
    }
}

public static void closeQuietly(@Nullable Logger log, @Nullable Process process) {
  try {
    close(process);
  }
  catch (Exception e) {
    //log if Logger provided, otherwise discard
    logError(log, "Fehler beim Schließen des Process-Objekts (inkl. underlying streams)!", e);
  }
}

public static void close(@Nullable Closeable closeable) throws IOException {
  if(closeable != null) {
    closeable.close();
  }
}

这些方法基本上用在finally块中。

我真正想知道的是这个实施是否安全?考虑以下问题:进程对象在其生命周期内是否始终返回相同的 stdin、stdout 和 stderr 流?或者我可能会错过关闭之前由进程返回的流'getInputStream(), getOutputStream() and getErrorStream()方法?

StackOverflow.com 上有一个相关问题:java:关闭子进程std流?

Edit

正如我和其他人在这里指出的:

  • 输入流必须被完全消耗。如果不完成,则子进程可能不会终止,因为其输出流中存在未完成的数据。
  • 所有三个标准流都必须关闭。不管以前用过还是没用过。
  • 当子进程正常终止时,一切都应该没问题。如果不是,则必须强制终止。
  • 当子进程返回退出代码时,我们不需要destroy()它。它已经终止了。 (即使不一定以退出代码 0 正常终止,但它还是终止了。)
  • 我们需要监控waitFor()并在超时时中断,以便进程有机会正常终止,但在挂起时杀死它。

未答复部分:

  • 考虑并行使用 InputStream 的优点和缺点。或者它们必须按特定顺序消耗?

尝试简化您的代码:

public static void close(@Nullable Process process) throws IOException
{
    if(process == null) { return; }

    try
    {
        close(process.getOutputStream());
        close(process.getInputStream());
        close(process.getErrorStream());

        if(process.waitFor() != 0)
        {
            process.destroy();
        }
    }
    catch(InterruptedException e)
    {
        process.destroy();
    }
    catch (RuntimeException e)
    {
        throw (e instanceof IOException) ? e : new IOException(e);
    }
}

通过捕捉Throwable我假设您希望捕获所有未经检查的异常。这要么是RuntimeException or Error。然而Error永远不应该被抓住,所以我已经替换了Throwable with RuntimeException.

(捕获所有内容仍然不是一个好主意RuntimeExceptions.)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何适当地从 java.lang.Process 关闭 std-streams? 的相关文章

  • Java中遍历所有文件

    我想让我的程序打印我计算机上所有文件的巨大列表 我的问题是 当我希望它打印位于我的计算机上的所有文件时 它仅打印第一个硬盘驱动器的第一个文件夹中的文件 有什么想法我在这里做错了什么吗 谢谢 这是我使用的代码 Main import java
  • 深入理解Java中的Volatile

    Java是否允许输出1 0 我已经对其进行了非常深入的测试 但无法获得该输出 我只得到1 1 or 0 0 or 0 1 public class Main private int x private volatile int g Exec
  • 从我们的 Java 程序执行 Java 程序

    I used Runtime getRuntime exec 但它抛出了IOException如下 java io IOException CreateProcess c error 5 at java lang Win32Process
  • 将 for 循环转换为 concat String 为 lambda 表达式

    我有以下 for 循环 它迭代字符串列表并将每个单词的第一个字符存储在StringBuilder 我想知道如何将其转换为 lambda 表达式 StringBuilder chars new StringBuilder for String
  • Gradle 发布两次尝试将 RPM 上传到 Artifactory YUM 存储库,第二次失败并显示 403

    我正在尝试使用 gradle 和 ivy publish 插件将 RPM 工件发布到 Artifactory 上的本地 YUM 存储库 我遇到的问题是 发布任务似乎尝试上传工件两次 第二次尝试失败 正确 HTTP 状态代码为 403 我进行
  • spring依赖注入会创建单例对象吗?

    spring内部是如何管理这些对象的呢 单例对象什么时候创建和销毁 默认情况下 Spring bean 基本上是单例的 Spring 将为每个类创建一个实例 并且通常会在 Spring 初始化时执行此操作 然而 这几乎是无限可定制的 Spr
  • 如何使用appium和java在Android中向下滚动以单击元素?

    我想知道如何使用appium和java向下滚动以单击Android中的元素 我里面有一个元素列表 android support v7 widget RecyclerView由于它有10多个元素 所以我们需要滑动屏幕才能看到下面的元素 每个
  • GSON:如何从 Json 中获取不区分大小写的元素?

    下面显示的代码在以下情况下效果很好JSON对象包含jsonKey因为它被传递给该方法 我想知道 是否有一种方法可以获取分配给不区分大小写的键表示的值 Example public String getOutputEventDescripti
  • 在jodatime中计算一个月的周数

    jodatime 可以计算一个月的周数吗 我需要这样的东西 月份 七月 第 27 年的一周 1 7 七月 第 28 年的一周 9 14 七月 第 29 年的一周 16 21 七月 第 30 年的一周 23 31 七月 月份 八月 第 31
  • 在“Java Web 服务教程”之后找不到 taskdef 类 com.sun.tools.ws.ant.WsImport

    我在许多不同的地方看到了同样的问题 即使经过大量谷歌搜索 我也无法解决它 我想做的 更大的图景 是经历Java Web 服务教程 http download oracle com docs cd E17802 01 webservices
  • 从枚举返回计算值

    我的问题有两个而且很简单 按原样误解枚举 这个想法在我的代码中缺少一些重要的抽象 代码示例 其中oprt calc x y 无法编译 有警告cannot find symbol public enum Operation PLUS publ
  • 信用卡号应该存储为字符串还是整数?

    是啊 只是想想而已 我应该将在我的网站上输入的信用卡号存储为字符串还是整数 我的意思是 它们由数字组成 这让我认为它是一个整数 但我不对它们进行数学运算 所以也许字符串更合适 编辑 所以我必须在加密之前存储在某个时刻输入的数字 我可能应该更
  • java中接口上的抽象方法是什么[重复]

    这个问题在这里已经有答案了 可能的重复 为什么要将 Java 接口方法声明为抽象方法 https stackoverflow com questions 641536 why would one declare a java interfa
  • Java 8 元空间垃圾收集

    我正在运行的 java 进程在运行的第一个小时左右始终表现良好 然而 性能会迅速下降 在分析时 我发现元空间垃圾收集相当频繁地发生 直到小时标记 然后失去控制 我相当确定我能够使用 XX MaxMetaspaceSize 选项来解决此问题
  • Web 服务器上的身份验证和授权 ?

    我正在构建一个 Android 应用程序 它与 apache tomcat 上的 Web 服务器进行通信 Web 服务器采用 JAVA EE 构建 目前 为了进行身份验证和授权 我使用用户名 密码 为了管理会话 我使用令牌 因此 当用户登录
  • 使用Optional进行空检查

    我想使用可选实用程序在 JDK8 中执行空检查 这是我正在编写的代码 它给了我一个错误 java util Optional stringToUse java util Optional of childPage getContentRes
  • JavaFX ComboBox - 显示文本但在选择时返回 ID

    我有一个包含机场的数据库表 每个机场都有一个名称和一个 ID 在 JavaFX 中我有一个表单 其中包含ComboBox 组合框需要显示所有机场名称 并且在提交表单时需要将机场的 ID 插入数据库 而不是其名称 但我并没有真正弄清楚解决方案
  • 如何用java实现FTP?

    我正在使用 FTP 我必须在客户端将消息嵌入到图像文件中 并且我必须将其发送到服务器 在服务器端我必须检索图像文件并然后我将检索该消息 我已经完成了嵌入消息并使用密码学和隐写术技术检索消息 我正在寻找如何将该文件从客户端传输到服务器 我必须
  • 我可以在Java中设置枚举起始值吗?

    我使用枚举来创建一些常量 enum ids OPEN CLOSE OPEN 值为零 但我希望它为 100 这可能吗 Java 枚举与 C 或 C 枚举不同 后者实际上只是整数的标签 Java 枚举的实现更像是类 它们甚至可以有多个属性 pu
  • JDK1.6 中 ManagementFactory 的托管 Mbean - NotCompliantMBeanException:

    我使用 ManagementFactory 来获取 JDK1 5 和 JBOSS 4 X 中的 ManagedMbeans 现在想将我的相同代码移至 JDK 1 6 Mbean 部分中断并抛出异常 引起原因 javax management

随机推荐

  • Java 和 HID 通信

    我正在寻找为简单的无线 HID 接口设备编写一个 Linux Windows Mac Java HID 控制器 我对 USB4Java LibUsb 库进行了修改 但没有成功 我已经转向 JavaHIDAPI 的方向 不幸的是 对我来说 除
  • 如何在 SQL (Excel) 中传递参数进行查询

    我将 Excel 链接 到 Sql 它工作得很好 我编写了一些 SQL 脚本 它工作得很好 我想做的就是将参数传递给查询 就像每次刷新一样 我希望能够将参数 过滤条件 传递给 Sql 查询 在 连接属性 中 参数按钮被禁用 所以我无法进行参
  • Spring cron 与普通 cron 比较?

    我试图让 cron 作业在遗留的 Java Spring Hibernate 项目中工作 所以我决定使用 spring 调度程序 我希望 myTask doStuff 在每月第一个星期日的 12 00 运行 在我的 application
  • 二分查找,终止条件为“left < right”,步长更新为“left = mid +1,right = mid”

    我正在读leetcode中的二分查找模板二 它用于搜索需要的元素或条件访问当前索引及其直接右邻居的索引在数组中 def binarySearch nums target type nums List int type target int
  • Java并发修改异常

    我编写了以下代码 导致并发修改异常 我该如何预防呢 这个想法是转义 Map 的所有值并使用新的参数映射重建对象 dO try Map
  • 删除列标签的背景颜色,同时保留绘图背景颜色 ggpairs

    我定义了一个函数来设置 ggpairs 中的背景 以匹配两个变量之间的相关程度 但是 我还想从沿图外部运行的变量标签中删除灰色背景 但如果不删除相关颜色 我就无法做到这一点 library GGally Loads some data mt
  • 在cuda中求对数

    如何在cuda中找到对数 我正在寻找设备功能 Thanks 您可以使用 logf x logf x log2f x log2f x log10f x log10f x 取自CUDA 编程指南 附录 D
  • 在cuda中分配结构数组后变量丢失

    我有一个用 C 语言编写的结构体 其中包含结构体数组 我需要在 GPU 中复制该结构体 为此 我正在编写一个函数 使一些cudaMalloc and cudaMemcpy从主机到设备的结构体中的变量 该结构的一个简单版本 真正的版本内部有各
  • java中为什么需要方法重载和重写? [复制]

    这个问题在这里已经有答案了 可能的重复 多态 重写 重载 我很难知道为什么需要方法重载和覆盖在java中 我读过一些关于此的文章 但无法理解为什么实际上需要它 我还访问了 stackoverflow 中的以下网址 但我还不清楚这个主题 Ja
  • 使用 Entity Framework 4 数据注释进行日期范围验证

    我使用 Entity Framework 4 为 ASP NET MVC3 Razor2 Web 应用程序提供模型 我正在使用 DataAnnotations 来实现验证 我需要将某些日期限制在 SQL Smalldatetime 类型接受
  • jpa 获取连接查询

    这是我的域名的样子 public class Template implements Serializable private static final long serialVersionUID 1L OneToOne cascade C
  • Excel 2007 MS Query 中出现多部分标识符错误,但 SQL Server 2008 中没有

    我有以下 SQL 代码 SELECT pd1 Meter pd1 BasicPool pd1 RateClass pd1 Flowdate SELECT upOrDownContract FROM PipelineData pd WHERE
  • 如何在后台显示 Swift UI 中的通讯通知?

    我正在 SwiftUI 和 firebase 中制作一个聊天应用程序 我想在用户收到新消息时显示通知 我能够在 firebase 中使用云消息发送推送通知 但这些通知不会自动发送 现在我想在用户收到消息时自动发送通信通知 我无法在 swif
  • 如何在 CDE 中添加全选选项来选择组件

    对于学生项目 我们正在与 Pentaho CDE 合作创建一个仪表板 一开始它工作得很好 但现在我们正处于添加多个选择组件的阶段 我们将选择组件的参数插入到Where语句中的SQL查询中 但现在我们遇到了一个问题 即不可能选择一个选择组件中
  • 在 C 中使用 libcurl 保存文件

    我正在从 perl 扩展到 C 并且尝试使用curl 的库来简单地从远程 url 保存文件 但我很难找到一个很好的示例来工作 另外 我不确定是否应该使用curl easy recv或curl easy perform I find 这个资源
  • 使用 const 引用延长临时对象的寿命

    我需要一些关于 const 引用的澄清 从这个链接 const Foo myFoo FuncBar const 引用延长了本地对象的寿命 但当我检查时这个链接尽管他们使用了 const 引用 Sandbox const string n m
  • 如何将Struts 2操作类中的InputStream值传递给JSP页面中的Ajax并将该值转换为JSON数组

    我想将 JSON 数组从 Struts 2 操作类传递到 JSP 页面 我正在尝试将数据集作为字符串发送 我想知道的是 如何在 JavaScript 中读取这些数据 这是我的方法Action class private InputStrea
  • Javascript - 模拟 Chrome 53 上的按键事件

    我正在尝试模拟按键事件 按下 铬53 我在 StackOverflow 上找到的所有解决方案似乎都不起作用 我的目标是拥有一个函数keyCode并用它模拟按键 需要纯JS function keyPressSimulate keyCode
  • 更新实体框架 4.1 代码优先中的外键关联

    我得出的结论是 我应该在我的代码优先设计中定义独立关联和外键关联 例如 public class Book public int ID get set public int AuthorID get set ForeignKey Autho
  • 如何适当地从 java.lang.Process 关闭 std-streams?

    这个问题是关于java lang Process及其对 stdin stdout 和 stderr 的处理 我们的项目中有一个类是对org apache commons io IOUtils 我们有一个安静的新方法来关闭进程对象的标准流吗