从Java执行外部程序

时间:2010-05-20 14:22:37

标签: java macos terminal

我正在尝试从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。

如果我从"> OutputFileNames.txt"方法中删除getRuntime().exec(),则所有文件名都会在控制台上打印出来。但我需要将它打印到文件中。

另外,如果我将命令更改为:

Process p = Runtime.getRuntime().exec(
    "cmd \c dir > OutputFileNames.txt"); 

并在Windows上运行它,它运行并将结果打印在文件中也很完美。

我已经阅读了其他从Java执行其他应用程序的帖子,但似乎没有与我的问题有关。

我真的很感激我能得到的任何帮助。

谢谢,

3 个答案:

答案 0 :(得分:8)

要使重定向按写入方式工作,您需要执行以下操作:

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)方法仍然会出错。唯一的解决方案是将命令参数作为数组提供。

答案 1 :(得分:1)

要看几件事。

  • 检查程序运行的目录(通过以相同的方式运行pwd),然后检查以确保您有权写入该目录。
  • 查看该文件OutputFileNames.txt是否已存在(并检查权限)。
  • 如果文件确实存在,请将其删除并重新运行以查看是否重新创建该文件,如果有,则查看内容。
  • 尝试使用"/bin/bash -c 'ls > OutputFileNames.txt'"命令 - 可能bash输出 ls输出相同(在您的示例中,重定向可以申请bash而不是ls)。

答案 2 :(得分:1)

问题正在发生,因为进程的标准输出被定向到文件,因此java Process无法收集输出。

如果您希望将输出写入文件,并且可以在java中读取,那么您有两个选择:

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

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