【发布时间】:2011-01-10 04:18:15
【问题描述】:
在伪代码中,这就是我正在做的事情:
Process proc = runtime.exec(command);
processOutputStreamInThread(proc.getInputStream());
processOutputStreamInThread(proc.getErrorStream());
proc.waitFor()
但是,有时processOutputStreamInThread 看不到任何输出,有时却看到了。粗略地说,该方法会创建命令输出的BufferedInputStream 并将其发送到记录器。
根据我所看到的,我猜测 command 不需要将其所有输出转储到由 getInputStream() 和 getErrorStream() 提供的流中,从而允许流为空。
我的试验结果如下:
(1) java.lang.Process 中的 waitFor() 是否要求执行程序的输出在返回之前已被读取?
文档仅说明:
使当前线程在必要时等待,直到此
Process对象表示的进程终止。如果子进程已经终止,则此方法立即返回。如果子进程尚未终止,则调用线程将被阻塞,直到子进程退出。
(2)getInputStream和getErrorStream提供的流在什么情况下需要关闭和/或自动关闭?
文档仅说明:
获取子进程的错误流。流从这个 Process 对象表示的进程的错误输出流中获取数据。
实现说明:缓冲输入流是个好主意。
一个user reports 说他必须自己关闭流,但至少在部分时间我得到一个异常,表明当我尝试这样做时流已经关闭。
编辑:将getOutputStream 更改为getInputStream,现在出现在上面。
解决方案:问题最终是在某些情况下,用于处理输出流的线程直到我的非常短暂的进程完成后才会运行,从而导致输入流给出我没有数据。 waitFor 没有等待执行程序的输出。相反,程序在收集任何输出之前运行并终止。
我使用线程是因为我不确定我将在标准错误和标准输出上获得多少输出,并且我希望能够同时处理两者,而不会阻塞其中一个或另一个应该只有其中一个有数据可用的。但是,因为我的线程不能始终如一地读取执行程序的输出,所以这是一个非解决方案。
我的最终编码看起来像这样:
ProcessBuilder pb = new ProcessBuilder(cmdargs);
pb.redirectErrorStream(true);
Process proc = pb.start();
processOutputStream(proc.getInputStream());
proc.waitFor()
【问题讨论】:
标签: java multithreading process inputstream