同时运行外部程序并通过stdin / stdout与它通信

时间:2011-04-08 06:18:55

标签: java

我希望能够与我的Java代码同时运行外部程序,即我想启动程序,然后将控制权返回给调用方法,同时保持外部程序同时运行。然后,Java代码将继续生成输入并将其发送到外部程序并接收输出。

我不想继续加载外部程序,因为它有很高的开销。完成此任务的最佳方法是什么?谢谢!

5 个答案:

答案 0 :(得分:11)

看看ProcessBuilder。设置ProcessBuilder并执行start后,您将拥有Process的句柄,您可以向其输入输入和读取输出。

这是一个让你入门的片段:

ProcessBuilder pb = new ProcessBuilder("/bin/bash");
Process proc = pb.start();

// Start reading from the program
final Scanner in = new Scanner(proc.getInputStream());
new Thread() {
    public void run() {
        while (in.hasNextLine())
            System.out.println(in.nextLine());
    }
}.start();

// Write a few commands to the program.
PrintWriter out = new PrintWriter(proc.getOutputStream());
out.println("touch hello1");
out.flush();

out.println("touch hello2");
out.flush();

out.println("ls -la hel*");
out.flush();

out.close();

<强>输出:

-rw-r--r-- 1 aioobe aioobe 0 2011-04-08 08:29 hello1
-rw-r--r-- 1 aioobe aioobe 0 2011-04-08 08:29 hello2

答案 1 :(得分:2)

你可以用Runtime.getRuntime()启动外部应用程序.exec(...)

要将数据发送到外部程序,您可以在Processes输出流上发送数据(从exec获取Process对象),也可以打开套接字并以此方式进行通信。

答案 2 :(得分:0)

我认为您会发现课程java.lang.Process的Javadoc很有帮助。值得注意的是,您可以从Process获取输入和输出流,以便在它运行时与它进行通信。

答案 3 :(得分:0)

关于使用ProcessBuilder的答案。如果您想了解有关此问题的更多详细信息,以及为什么您希望将其更改为Runtime.exec(),请参阅此entry in the Java glossary。它还说明了如何使用线程与外部进程进行通信。

答案 4 :(得分:0)

由于阻塞,我试图通过stdin / stdout与外部进程实现双向通信时遇到问题。最后,我发现a github gist使我能够简单,优雅地解决问题;该要旨实际上是基于stackoverflow answer的。

请参见示例代码的其他答案,但该思想的核心是设置一个用于读取和写入的事件循环(休眠状态为10ms的while循环),并使用低级流操作,以便不进行缓存和阻塞继续进行-仅当您知道其他进程实际上写了东西(通过InputStream.available())时,才尝试阅读。

这导致了一种奇怪的编程风格,但是代码比使用线程时要简单得多,并且做得很好。