使用 Apache Commons Exec 向命令提供多个输入并提取输出时遇到问题

2023-11-27

我正在编写一个 Java 应用程序,需要使用 Apache Commons Exec 库的外部命令行应用程序。我需要运行的应用程序具有相当长的加载时间,因此最好保持一个实例处于活动状态,而不是每次都创建一个新进程。该应用程序的工作方式非常简单。一旦启动,它就会等待一些新的输入并生成一些数据作为输出,这两者都使用应用程序的标准 I/O。

因此,我们的想法是执行 CommandLine,然后将 PumpStreamHandler 与三个单独的流(输出、错误和输入)结合使用,并使用这些流与应用程序交互。到目前为止,我已经在基本场景中完成了这项工作,其中我有一个输入,一个输出,然后应用程序关闭。但当我尝试进行第二笔交易时,就出了问题。

创建 CommandLine 后,我创建 Executor 并启动它,如下所示:

this.executor = new DefaultExecutor();

PipedOutputStream stdout = new PipedOutputStream();
PipedOutputStream stderr = new PipedOutputStream();
PipedInputStream stdin = new PipedInputStream();
PumpStreamHandler streamHandler = new PumpStreamHandler(stdout, stderr, stdin);

this.executor.setStreamHandler(streamHandler);

this.processOutput = new BufferedInputStream(new PipedInputStream(stdout));
this.processError = new BufferedInputStream(new PipedInputStream(stderr));
this.processInput = new BufferedOutputStream(new PipedOutputStream(stdin));

this.resultHandler = new DefaultExecuteResultHandler();
this.executor.execute(cmdLine, resultHandler);

然后,我继续启动三个不同的线程,每个线程处理不同的流。我还有三个同步队列来处理输入和输出(一个用作输入流的输入,一个用于通知输出队列已启动新命令,另一个用于输出)。例如,输入流线程如下所示:

while (!killThreads) {
    String input = inputQueue.take();

    processInput.write(input.getBytes());
    processInput.flush();

    IOQueue.put(input);
}

如果我删除 while 循环并只执行一次,一切似乎都会完美运行。显然,如果我尝试再次执行它,PumpStreamHandler 会抛出异常,因为它已被两个不同的线程访问。

这里的问题是,在线程结束之前,processInput 似乎并未真正刷新。调试时,命令行应用程序仅在线程结束后才真正接收其输入,但如果保留 while 循环,则永远不会获取它。我尝试了很多不同的方法来刷新 processInput,但似乎没有任何效果。

以前有人尝试过类似的事情吗?我有什么遗漏的吗?任何帮助将不胜感激!


我最终找到了一种方法来完成这项工作。通过查看 Commons Exec 库的代码,我注意到 PumpStreamHandler 使用的 StreamPumpers 不会在每次有新数据传入时刷新。这就是为什么当我只执行一次代码时代码就可以工作,因为它会自动刷新并关闭流。因此,我创建了名为 AutoFlushingStreamPumper 和 AutoFlushingPumpStreamHandler 的类。后者与普通的 PumpStreamHandler 相同,但使用 AutoFlushingStreamPumpers 而不是通常的。 AutoFlushingStreamPumper 的功能与标准 StreamPumper 相同,但每次写入内容时都会刷新其输出流。

我已经对其进行了相当广泛的测试,并且看起来效果很好。感谢所有尝试解决这个问题的人!

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

使用 Apache Commons Exec 向命令提供多个输入并提取输出时遇到问题 的相关文章

  • Java 枚举与创建位掩码和检查权限的混淆

    我想将此 c 权限模块移植到 java 但是当我无法将数值保存在数据库中然后将其转换为枚举表示形式时 我很困惑如何执行此操作 在 C 中 我创建一个如下所示的枚举 public enum ArticlePermission CanRead
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • Spring AspectJ 在双代理接口时失败:无法生成类的 CGLIB 子类

    我正在使用Spring的
  • 从命令行添加 Xcode 开发者帐户

    我正在尝试使用xcodebuild allowProvisioningUpdates在我只能通过命令行访问的计算机 Azure Devops macOS 托管计算机 上 不幸的是 根据man xcodebuild为了使用 allowProv
  • 来自 dll 的 Java 调用函数

    我有这个 python 脚本导入zkemkeeperdll 并连接到考勤设备 ZKTeco 这是我正在使用的脚本 from win32com client import Dispatch zk Dispatch zkemkeeper ZKE
  • java.lang.IllegalStateException:提交响应后无法调用 sendRedirect()

    这两天我一直在尝试找出问题所在 我在这里读到我应该在代码中添加一个返回 我做到了 但我仍然得到 java lang IllegalStateException Cannot call sendRedirect after the respo
  • 每个托管线程是否都有自己对应的本机线程?

    我想知道是否在 Net 中创建托管线程 通过调用Thread Start 导致在后台创建一个本机线程 那么托管线程是否有对应的本机线程呢 如果是 当托管线程等待或睡眠时 是否意味着相应的本机线程也在等待或睡眠 是的 NET 线程映射到所有当
  • 使用 std::packaged_task/std::exception_ptr 时,线程清理程序报告数据争用

    我遇到了线程清理程序 TSan 的一些问题 抱怨某些生产代码中的数据争用 其中 std packaged task 通过将它们包装在 std function 中而移交给调度程序线程 对于这个问题 我简化了它在生产中的作用 同时触发 TSa
  • 像 Java 这样的静态类型语言中动态方法解析背后的原因是什么

    我对 Java 中引用变量的动态 静态类型和动态方法解析的概念有点困惑 考虑 public class Types Override public boolean equals Object obj System out println i
  • 在我的 Spring Boot 示例中无法打开版本 3 中的 Swagger UI

    我在 Spring Boot 示例中打开 swagger ui 时遇到问题 当我访问 localhost 8080 swagger ui 或 localhost 8080 root api name swagger ui 时出现这种错误 S
  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • java for windows 中的文件图标叠加

    我正在尝试像 Tortoise SVN 或 Dropbox 一样在文件和文件夹上实现图标叠加 我在网上查了很多资料 但没有找到Java的解决方案 Can anyone help me with this 很抱歉确认您的担忧 但这无法在 Ja
  • Eclipse 选项卡宽度不变

    我浏览了一些与此相关的帖子 但它们似乎并不能帮助我解决我的问题 我有一个项目 其中 java 文件以 2 个空格的宽度缩进 我想将所有内容更改为 4 空格宽度 我尝试了 正确的缩进 选项 但当我将几行修改为 4 空格缩进时 它只是将所有内容
  • 如何使用 jUnit 将测试用例添加到套件中?

    我有 2 个测试类 都扩展了TestCase 每个类都包含一堆针对我的程序运行的单独测试 如何将这两个类 以及它们拥有的所有测试 作为同一套件的一部分执行 我正在使用 jUnit 4 8 在 jUnit4 中你有这样的东西 RunWith
  • Cucumber 0.4.3 (cuke4duke) 与 java + maven gem 问题

    我最近开始为 Cucumber 安装一个示例项目 并尝试使用 maven java 运行它 我遵循了这个指南 http www goodercode com wp using cucumber tests with maven and ja
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • Android 中的处理程序与异步调用

    目前我正在使用处理程序来调用 Web 服务方法以使其在后台运行 问题是它需要更多的时间来给出响应 在性能方面似乎更昂贵 现在我计划使用异步调用 哪一个是最好的 Android 中的处理程序和异步调用有什么区别 请帮我想出一个最好的解决方案
  • 如何使用mockito模拟构建器

    我有一个建造者 class Builder private String name private String address public Builder setName String name this name name retur
  • 使用 CXF-RS 组件时,为什么我们使用 而不是普通的

    作为后续这个问题 https stackoverflow com questions 20598199 对于如何正确使用CXF RS组件我还是有点困惑 我很困惑为什么我们需要
  • 双枢轴快速排序和快速排序有什么区别?

    我以前从未见过双枢轴快速排序 是快速排序的升级版吗 双枢轴快速排序和快速排序有什么区别 我在 Java 文档中找到了这个 排序算法是双枢轴快速排序 作者 弗拉基米尔 雅罗斯拉夫斯基 乔恩 本特利和约书亚 布洛赫 这个算法 在许多数据集上提供

随机推荐

  • node-postgres如何转义参数?

    我知道关于参数化查询 但由于我必须以编程方式构造哪里条件 计算参数的数量并构建参数数组是一项比简单地调用escape需要时发挥作用 所以 node postgres 中有参数转义函数吗 Yes since this PR there are
  • 如何使用 cin 读取 double 的整个值?

    long double m cout lt lt enter double cin gt gt m cout lt lt m lt lt m lt
  • 如何将日期转换为月份数?

    我有一个专栏Month在我的桌子上 月份名称和日期存储在本月列中 例如 Month 01 JAN 12 02 FEB 12 等等 我如何convert the DATE转换为月份数字 例如 Month 1 2 etc select to c
  • “shouldOverrideUrlLoading”真的被弃用了吗?我可以用什么来代替?

    shouldOverrideUrlLoading 真的被弃用了吗 如果是这样 我可以用什么来代替 这好像是shouldOverrideUrlLoading已弃用针对 Android N我需要让一个应用程序从 API 19 开始工作 直到现在
  • 如何在 Android 浏览器中启用安全搜索

    要求 我的浏览器要求在浏览时启用 禁用安全搜索 On Google 安全搜索页面 使用安全搜索阻止 Google 上的露骨搜索结果 您可以过滤 Google 上的露骨搜索结果 例如色情内容 使用安全搜索设置 安全搜索并非 100 准确 但它
  • 如何使用 adb shell 移动文件?

    如何使用 adb shell 移动文件 例如我想将 SystemUI apk 从 system 移动到 system app 我没有找到任何使用 adb shell 在系统分区内移动文件的命令 有谁知道该怎么做 Does mv不行 mv s
  • 在析构函数中正确使用 std::uncaught_exception

    有一些文章的结论是 永远不要从析构函数抛出异常 和 std uncaught exception 没有用 例如 http www gotw ca gotw 047 htm 赫伯 萨特撰写 但我似乎没有明白这一点 所以我写了一个小的测试示例
  • C++ 11 future_status::deferred 不起作用

    include
  • 将 bash 数组传递给 python 列表

    我正在尝试使用旧的 getenv 方法将数组从 bash 传递到 python 但是我不断收到此错误 crcFiles sh line 7 export 0021 not a valid identifier Traceback most
  • ILMerge 和 .NET 4.0 存在严重问题

    在我的一生中 我似乎无法将我的 NET 4 应用程序与 ILMerge 正确合并 即使在设置 targetplatform lib ndebug 之后and添加自定义 ILMerge exe config 文件后 输出文件无法正常工作 它似
  • 使用 MPI_Type_create_subarray 发送时可以转置数组吗?

    我正在尝试使用 C 中的 MPI 转置矩阵 每个进程都有一个方形子矩阵 我想将其发送到正确的进程 网格上的 相反 进程 将其转置作为通信的一部分 我在用着MPI Type create subarray其中有一个关于顺序的参数 要么MPI
  • JSF 中的多个动作监听器

    我想在进一步处理之前使用多个操作侦听器来设置两个支持 bean 的状态 1st way
  • 如何从有符号的零中去掉负号

    我正在使用 asin 来计算角度 代码如下 double FindAngle const double theValue return asin theValue 当参数 theValue 0 0 时 FindAngle 返回 0 0 有符
  • 使用纯 CSS 创建 CSS 网格布局

    我尝试使用 CSS 网格创建一个布局 如图所示 任何项目都是方形的 我正在尝试的代码 CSS grid container padding 20px display grid grid gap 20px grid auto rows 1fr
  • GNU C++ 标准库使用哪种算法来计算指数函数?

    请考虑std exp标头中定义cmath in C numerics图书馆 现在 请考虑 C 标准库的实现 例如libstdc 库 考虑到有各种算法计算初等函数 例如算术几何平均迭代算法计算指数函数和其他三个函数here 您能否说出用于计算
  • 如何向 Interface Builder 中的 NSMenu 添加附加项目?

    我是第一次使用 Xcode 我一直在关注教程 但我完全被一些微不足道的东西难住了 我已将 菜单 从库拖到 MainMenu xib 窗口中 双击该菜单即可出现 到目前为止没有遇到任何麻烦 编辑这三个项目和删除项目一样直观 我到底该怎么办ad
  • PhoneGap 3.3 iOS KeyboardShrinksView

    在 PhoneGap Cordova 3 3 和 3 2 中 首选项键盘收缩视图iOS 版已经消失并被替换为启用ViewPortScale 任何人都可以向我解释如何实现与 KeyboardShrinksView 相同的结果 但通过使用 en
  • 设置带有骨干的下拉选择值

    我想从我的 js 设置下拉菜单 基本上 我希望能够从 js 设置更新的下拉值 my html div class dropDownList div
  • Firebase @PropertyName 不起作用

    故事 我在我的应用程序中使用 Firebase 实时数据库 我有一个类似这样的模型 class Item int mItemName Simplified for brevity 现在 这将该字段存储为itemName在我的实时数据库中 但
  • 使用 Apache Commons Exec 向命令提供多个输入并提取输出时遇到问题

    我正在编写一个 Java 应用程序 需要使用 Apache Commons Exec 库的外部命令行应用程序 我需要运行的应用程序具有相当长的加载时间 因此最好保持一个实例处于活动状态 而不是每次都创建一个新进程 该应用程序的工作方式非常简