【发布时间】:2010-05-22 10:01:17
【问题描述】:
这是在本地Processing 程序的上下文中。我想运行一个外部程序来获取一些数据。有没有我可以使用的 popen() 或等效函数?
【问题讨论】:
这是在本地Processing 程序的上下文中。我想运行一个外部程序来获取一些数据。有没有我可以使用的 popen() 或等效函数?
【问题讨论】:
popen() 的一个好朋友是将命名管道作为输入和/或输出,就像在 UNIX 中一样:
mknod /tmp/mypipe.12345 p ; sort -o /tmp/mypipe.12345 /tmp/mypipe.12345 &
然后打开/tmp/mypipe.12345,写入,关闭,打开/tmp/mypipe.12345,读取,关闭。由于在输入EOF 之前排序无法写入任何内容,因此输出打开将在输入关闭后发生。 popen() 电话不能这样做!
对于更简单的场景,命名管道只能被读取或写入。
当然,您仍然需要将其拆分,就像在 system(...) 通话中一样。
您想在完成后删除命名管道。在某些 UNIX 系统上,/tmp 在重新启动时被清除。
/tmp 是共享的,因此很可能发生名称冲突。您可以在 Java 中生成部分随机的管道文件名(/tmp/mypipe.12345 的数字部分)以防止这种情况发生。在某些系统中,Bash 会在 /var/tmp 中为每个 <(...) 或 >(...) 的使用创建命名管道。不幸的是,要确定何时可以将它们移除而没有效果(热熔器?)有点挑战!
【讨论】:
Process process = Runtime.getRuntime().exec("your command");
然后您可以使用Process 流读取和写入数据。
【讨论】:
JDK5 引入了ProcessBuilder 以更好地控制进程生成。
Process process = new ProcessBuilder(command).start()
请注意,在内部调用了 forkAndExec,并且 fork '制作了整个父地址空间的副本',因此当父进程具有大量内存空间时,即使是一个小命令也可能导致 OutOfMemoryErrors获得。
【讨论】: