从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中读取,那么您有两个选择:

  1. 保持重定向到位,然后从java中的OutputFile.txt中读取列表,例如使用new FileReader("OutputFile.txt") 。 请注意, exec()是异步的,并且可以在进程写入文件之前返回,因此您需要使用Process.waitFor()等待Process退出。
  2. 删除重定向,并直接将列表读入java(正如您所做的那样。)然后,您可以使用FileWriter将此列表写入文件。

最重要的是,您不能同时使用重定向和读取Process的输出 – 它是一个或另一个。

编辑:您的意见表明1)是首选方法。 这会将输出写入一个文件(使用OS shell),然后在进程退出时从java中读取该文件。