我希望能够与我的Java代码同时运行外部程序,即我想启动程序,然后将控制权返回给调用方法,同时保持外部程序同时运行。然后,Java代码将继续生成输入并将其发送到外部程序并接收输出。
我不想继续加载外部程序,因为它有很高的开销。完成此任务的最佳方法是什么?谢谢!
答案 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())时,才尝试阅读。
这导致了一种奇怪的编程风格,但是代码比使用线程时要简单得多,并且做得很好。