由Runtime exec运行时的外部程序块

时间:2009-12-05 00:59:00

标签: java runtime external execute runtime.exec

我正在尝试从java应用程序中启动VideoLAN程序的实例。我尝试这样做的方法之一如下所示:

Process p = Runtime.getRuntime().exec("\"C:\\Program Files\\VideoLAN\\VLC\\vlc.exe\" \"http://www.dr.dk/Forms/Published/PlaylistGen.aspx?qid=1316859&odp=true\" :sout=#std{access=udp,mux=ts,dst=127.0.0.1:63928}");

如果我执行上述命令,vlc程序将启动,并将启动流操作(它通过连接,缓冲然后流式传输)。

当Runtime exec(或ProcessBuilder启动)执行命令时,vlc程序将在缓冲阶段结束时挂起。如果java程序中的所有线程都终止/运行到结束,则vlc程序将进入流式阶段。在vlc进程关闭之前,java进程不会终止,因此这种行为显然是进程之间某种耦合的结果。

尝试通过将命令写入.cmd文件然后执行它来间接执行命令,但会导致相同的行为。

关于如何避免外部流程挂起的任何想法?

2 个答案:

答案 0 :(得分:7)

嗯,我的猜测是VLC填满你的STDOUT缓冲区并挂在printf语句中,因为STDOUT正在等待该缓冲区清空。

您需要获取流程输出的流并读取它(即使您将其丢弃)。

我建议您阅读此article

在第4页是一个很好的例子,说明如何读取线程中的流,这样你的子进程就不会阻塞。

答案 1 :(得分:0)

这个网站很棒:)。出于某种原因,我认为已经尝试过的方法突然开始起作用。

问题是vlc写入stdErrOut(在提示中执行时不可见)。一旦某个输出缓冲区已满,它就会阻塞。解决方案是将stdErr重定向到stdOut,然后让一个线程清空进程对象的输入流。

然而,这不是最佳解决方案,因为我需要相当数量的外部进程,并且您无法在其输入流上执行非阻塞I / O.稍微试验一下,让计时器服务驱动器空读取多个进程。关于如何解决过程以避免此问题的其他建议非常受欢迎。