2012-02-21 166 views
0

我必须编写一个程序,这个程序需要通过命令行调用来运行其他几个程序。程序1产生程序2然后读取的文件。我已经遵循了关于如何安全地执行此操作的各种示例,但仍然存在一个烦人的问题。下面的代码很大程度上工作,但只有之后的system.out存在。如果我拿出来,我会得到错误(见下文)。如果我不知道为什么发生了什么,我对代码有点不舒服。Java运行时进程waitfor没有出现等待

任何帮助表示赞赏。

代码:

public static int executeCommandWithOutputfile(String command, 
     String outputFile) { 
    int exitVal = 0; 

    try { 
     FileOutputStream fos = new FileOutputStream(outputFile); 
     Runtime rt = Runtime.getRuntime(); 
     Process proc = rt.exec(command); 

     // any error message? 
     StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), 
      "ERROR"); 

     // any output? 
     StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), 
      "OUTPUT", fos); 

     // kick them off 
     errorGobbler.start(); 
     outputGobbler.start(); 

     // any error??? 
     exitVal = proc.waitFor(); 
     //don't remove this system out, when I did I got errors. 
     //System.out.println("ExitValue: " + exitVal); 
     fos.flush(); 
     fos.close(); 
    } catch (Throwable t) { 
     t.printStackTrace(); 
    } 
    return exitVal; 
} 

输出与System.out的线完好:

ExitValue: 0 
    ExitValue: 0 
    ExitValue: 0 
    Release note complete. 

输出与System.out的移除:

[Fatal Error] tmpRelNote2482381115742032425xml:1:1: Premature end of file. 
    Error : The XML config file is not valid! 
    Exception in thread "main" java.lang.NullPointerException 
     at rwe.release.CreateReleaseNote.insertReleaseInfo(CreateReleaseNote.java:96) 
     at rwe.release.CreateReleaseNote.writeReleaseNote(CreateReleaseNote.java:81) 
     at rwe.release.CreateReleaseNote.<init>(CreateReleaseNote.java:30) 
     at rwe.release.CreateReleaseNote.main(CreateReleaseNote.java:19) 
    Process exited with exit code 1. 
+0

您应该在'insertReleaseInfo()'中显示出现异常的位置。 – Viruzzo 2012-02-21 16:50:37

+0

在到达waitFor()之前,您似乎遇到错误。当您尝试在调试器中调试代码时,您会看到什么? – 2012-02-21 16:57:55

回答

2

你的代码有竞争条件。当您致电fos.close()时,OutputGobbler可能会或可能不会完成吞吐过程的输出。 println减慢了这个线程,足以让狼吞虎咽的时间来完成处理输出的过程。

必须确保OutputGobbler已完成将所有输出传输到文件,然后再关闭文件。

+0

added errorGobbler.join(); and outputGobbler.join();现在所有的工作,感谢大卫 – Chris 2012-02-22 14:05:02

0

你确定这个问题是与waitFor()?

我认为问题在于刷新外部命令的OutputStream,这就解释了为什么System.out.println()修复了这个问题。尝试在waitFor()返回后执行显式的System.out.flush()。 “创建的子进程没有自己的终端或控制台,它的所有标准io(即stdin,stdout,stderr)操作将通过三个流(getOutputStream(),getInputStream())重定向到父进程, (),getErrorStream())。“