从Java执行外部程序
我正在尝试从Java代码执行程序。 这是我的代码:
public static void main(String argv[]) { try { String line; Process p = Runtime.getRuntime().exec( "/bin/bash -c ls > OutputFileNames.txt"); BufferedReader input = new BufferedReader( new InputStreamReader(p.getInputStream())); while ((line = input.readLine()) != null) { System.out.println(line); } input.close(); } catch (Exception err) { err.printStackTrace(); } }
我的操作系统是Mac OS X 10.6。
如果我从getRuntime().exec()
方法中删除"> OutputFileNames.txt"
,则所有文件名都会在控制台上打印出来。 但我需要将它打印到文件中。
另外,如果我将命令更改为:
Process p = Runtime.getRuntime().exec( "cmd \c dir > OutputFileNames.txt");
并在Windows上运行它,它运行并在文件中打印结果也很好。
我已经阅读了其他从Java执行另一个应用程序的post,但似乎没有一个与我的问题有关。
我真的很感激我能得到的任何帮助。
谢谢,
要使重定向按写入方式工作,您需要执行以下操作:
Process p = Runtime.getRuntime().exec( new String[]{"/bin/bash", "-c", "ls > OutputFileNames.txt"});
您遇到的问题是Runtime.exec(String)
将命令行拆分为参数的简单方法。
如果您要在shell提示符下运行该命令(原样),则必须将其输入为:
$ /bin/bash -c "ls > OutputFileNames.txt"
因为“bash”的“-c”选项要求将生成的shell的命令行作为单个shell参数。 但是如果你将裸引号放入Java String中, Runtime.exec(String)
方法仍然会出错。 唯一的解决方案是将命令参数作为数组提供。
有几件事要看。
- 检查程序运行的目录(通过以相同的方式运行
pwd
),然后检查以确保您有权写入该目录。 - 查看该文件
OutputFileNames.txt
已存在(并检查权限)。 - 如果文件确实存在,请将其删除并重新运行以查看是否重新创建该文件,如果存在则查看内容。
- 尝试使用命令
"/bin/bash -c 'ls > OutputFileNames.txt'"
– 可能是bash
输出与ls
输出不同(在你的例子中,重定向可能适用于bash
而不是ls
) 。
问题正在发生,因为进程的标准输出被定向到文件,因此java Process
无法收集输出。
如果您希望将输出写入文件,并且可以在java中读取,那么您有两个选择:
- 保持重定向到位,然后从java中的OutputFile.txt中读取列表,例如使用
new FileReader("OutputFile.txt")
。 请注意,exec()
是异步的,并且可以在进程写入文件之前返回,因此您需要使用Process.waitFor()
等待Process退出。 - 删除重定向,并直接将列表读入java(正如您所做的那样。)然后,您可以使用
FileWriter
将此列表写入文件。
最重要的是,您不能同时使用重定向和读取Process的输出 – 它是一个或另一个。
编辑:您的意见表明1)是首选方法。 这会将输出写入一个文件(使用OS shell),然后在进程退出时从java中读取该文件。