2011-01-12 54 views
1

当我在一个单独的进程执行命令,例如通过使用Runtime.getRuntime().exec(...)方法,其JavaDoc的状态:如何处理来自外部进程的不需要的流?

Executes the specified command and arguments in a separate process. 

什么我需要从这个过程中,流做,知道这一进程应活直到Java程序存在? (这是一个细节,但是Java程序需要关注杀死这个进程,而且该进程本身内置了一个安全的地方,如果它注意到Java程序导致他不再运行的话)。

如果我们认为这个进程完全没有输出(例如因为所有的错误消息和stdout都被重定向到/ dev/null,并且所有的通信都是使用files/sockets/whatever来完成的话),我需要做什么与输入流?

我应该有一个(或两个?)Java线程什么都不运行,试图读取stdout/stderr?

处理从Java程序产生的长时间生存的外部进程的正确方法是什么?它根本不产生stdout/stderr?

编辑

基本上我在另一个shell脚本,确保一切重定向到的/ dev/null的包裹shell脚本。如果我的“outter”shell脚本(将所有内容重定向到/ dev/null)仍然会在stdoutstderr上生成任何内容,我很确定我的Un * x不符合要求。然而,我发现它让我大开眼界,认为我应该在应用程序的生命周期中运行线程“毫无用处”。真的让人头晕目眩。

回答

1

如果一切都如你所说,那么你可能会忽略它们。

然而,很少这样干净地工作。以防万一,为了防止stdout/stderr产生单个线程,从长远来看,这可能是值得的。有一天它失败了,实际上是抛出一些东西,那就是你需要知道发生了什么的那一天。 1或2个线程(我认为只需要一个线程就可以完成)不会有太大的开销。特别是如果你是正确的,并且没有任何东西从这些流中出来。

+0

有趣。我将编辑我的问题......基本上我将shell脚本包装在另一个shell脚本中,确保将所有内容重定向到*/dev/null *。我非常确定,如果我的“outter”shell脚本(将所有内容重定向到*/dev/null *)仍然会在* stdout *或* stderr *上生成任何内容,我的Un * x将不符合要求。 – SyntaxT3rr0r 2011-01-12 21:33:53

+0

@ SyntaxT3rr0r - 我明白。我只是那些偏执狂的人之一。 :)我同意多余的线程可能是不必要的。 – rfeak 2011-01-12 21:37:46

1

我相信,如果您对它们不感兴趣,正确处理流程的输入和输出的方法是及时关闭它们。如果子进程随后试图分别调用stdin或stdout上的读或写操作,则会抛出IOException。儿童进程负责处理它不能读写的事实。

大多数进程将忽略这样一个事实,即他们无法写入并默默丢弃和写入。在Java中,这是真的,其中System.out是PrintWriter,所以由stdout引发的任何IOException都被忽略。这几乎是将输出重定向到/ dev/null时发生的情况 - 所有输出都被默默丢弃。

听起来好像你已经阅读了关于进程的API,以及为什么对进程进行读/写是很重要的,如果它期望自己做任何写或读的话。但我会重申,问题在于某些操作系统只为(特别是)标准输出分配了非常有限的缓冲区,所以重要的是不要让这些缓冲区填满。这意味着要么及时读取子进程的任何输出,要么通知操作系统您不需要输出进程,并且可以释放所有持有的资源,并拒绝进一步尝试写入标准输出或从标准输入读取(而不是不仅仅是悬在资源可用之前)。

相关问题