2

我正在使用 Java 的 ProcessBuilder 类来运行外部进程。进程不应在 Java 程序终止之前终止;它必须在命令/响应模式下保持活跃。

我知道如果忽略进程流很容易“堵塞”,所以我做了以下事情:程序在“读取器”线程中读取进程的组合输出和错误流,并使用“写入器”线程来管理命令. 读取器线程从进程输出中读取阻塞字符,将它们缓冲到字符串中并分派结果。编写器线程通过 PrintWriter 编写完整的“命令”行;它使用队列来确保没有两个命令写入“靠得太近”(当前为 100 毫秒),并且在前一个命令的输出完成之前不会写入新命令。在每次 println() 之后,我也会调用 flush() 和 checkError()。

该方案可以正常工作几秒钟或几分钟,然后读取器线程挂起阻塞 read()。没有错误,没有抛出异常,没有更多的流程输出。此后,没有什么可以恢复外部进程(除了重新启动它)。(顺便说一句,这发生在 Linux 和 Windows 上。)

我已经查看了 Jakarta Commons Exec 和 Plexus Utils http://plexus.codehaus.org/plexus-utils/中的代码和测试用例,但是(a)都没有给出使用长期进程的示例和( b)似乎两者都没有做任何与我所描述的基本不同的事情。

请问有人知道这里发生了什么吗?谢谢!

4

3 回答 3

1

我在三个单独的线程中实现了错误、输入和输出流,我可以毫无问题地读写外部进程。

我在 windows/linux 上使用大量内置应用程序 cmd/bash 以及其他 cmd 行二进制文件进行了测试,它工作正常,除了在某些情况下它只是抛出 io 流异常,我所做的是捕获异常并再次重新启动线程,以便该程序继续工作。

如果您尝试在 linux 中使用 ssh,那么您可能会遇到无法写入相同标准输入的问题,这是出于安全原因。

尝试从 System.in 获取输入,看看它是否有效,它在我的情况下有效

于 2011-12-07T16:12:52.177 回答
1

你也有管理stderr的线程吗?你只提到了两个流。

于 2009-10-29T12:58:20.677 回答
0

只是一个猜测,但您是否尝试过取消组合错误和输出流?

于 2009-10-29T13:00:55.453 回答