2010-05-20 111 views
1

我试图从Java代码执行程序。这里是我的代码:从Java执行外部程序

public static void main(String argv[]) { 
    try { 
     String line; 
     Process p = Runtime.getRuntime().exec(new String[]{ 
      "/bin/bash", "-c", "executable -o filename.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。

现在,我试图运行的可执行文件应该吐出输出到filename.txt。如果我使用此命令并在终端上运行它,它会正常工作,并且filename.txt也会被填充。但是,从我的Java程序文件不创建。

如果我使用可执行文件> filename.txt,那么filename.txt被创建,但是是空的。不知道这里有什么问题。我试图运行的可执行文件是Xtide(如果有帮助的话)。

我真的很感谢任何帮助,我可以得到。

感谢,

+0

这是来自http://stackoverflow.com/questions/2874591/execute-external-program-from-java/2874687#2874687的后续内容。 – mdma 2010-05-20 15:43:01

回答

2

你不能重定向输出到文件和读取Java中的输出。它是一个或另一个。你想要的是这样的:

 Process p = Runtime.getRuntime().exec(new String[]{ 
      "/bin/bash", "-c", "executable -o filename.txt"}); 
     p.waitFor(); 
     BufferedReader input = new BufferedReader(
      new InputStreamReader(new FileInputStream("filename.txt"))); 
     while ((line = input.readLine()) != null) { 
     System.out.println(line); 
     } 

的主要变化是:

  • p.waitFor(),因为流程的执行是异步的,所以你必须等待它完成。
  • 将数据从文件而不是从过程的输出读取(因为这将是空的。)
+0

这样做的主要问题是filename.txt没有被我的程序创建。如果我在终端上使用完全相同的命令,它会创建。你能想到任何原因为什么会发生?我已经设置了该文件夹的所有读/写权限。 – 2010-05-20 15:22:46

+0

我会在命令中创建文件名,并在创建FileInputStream绝对时创建文件名,以免遇到任何工作目录问题。 – mdma 2010-05-20 15:24:48

+0

@Saurabh作为一个猜测,过程因为没有添加p.waitFor()而提前终止。 – 2010-05-20 15:27:10

1

从摇头丸工程(我投它)的答案,但你可能还需要考虑在哪里你直接从executable读取输出数据流的版本:

Process p = Runtime.getRuntime().exec(new String[]{ 
      "/bin/bash", "-c", "executable"}); 
p.waitFor(); 
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream())_; 
while ((line = input.readLine()) != null) { 
    System.out.println(line); 
} 
+0

这是我第一次尝试。它没有这样工作,因此现在我试图将输出吐到一个文件然后读取它。 – 2010-05-20 15:34:08

0

纠正我,如果我错了,但症状如下:

  • exec("/usr/bash", "-c", "executable > filename.txt")创建一个空文件。
  • exec("/usr/bash", "-c", "executable -o filename.txt")不创建文件。
  • 上面的一个或两个都给出了一个退出代码255当你看它。
  • 当您从命令行运行命令executable -o filename.txtexecutable > filename.txt它按预期工作。

在上面的光,我认为最可能的原因是/bin/bash没有找到executable当您从Java启动它。第一个示例创建空文件的事实意味着/bin/bash正在做某件事。但是,如果你尝试从一个bash shell中运行

$ unknown-command > somefile.txt 

提示,你会得到一个错误信息说,该命令无法找到和一个空的“something.txt”文件。 (您的Java应用程序中看不到错误消息,因为它正在写入stderr,而您没有捕获它。)创建空的“something.txt”文件的原因是它由shell 之前它试图分叉并执行“可执行文件”。

如果这是问题,那么简单的解决方案是使用可执行文件的绝对路径名。另外,如果您没有执行任何命令行重定向或其他shell魔术,则不需要在新的bash实例中运行可执行文件。相反,只是这样做:

Process p = Runtime.getRuntime().exec("executable", "-o", filename.txt"); 

然后等待该过程完成,并试图读取该文件内容之前检查退出代码。

+0

这是对我答案中的评论的一个很好的解释! :) – mdma 2010-05-21 10:24:33

+0

@mdma - 我觉得我做的比这更多...... – 2010-05-21 13:14:31