我必须编写一个程序,通过命令行调用运行其他几个程序。程序1生成一个程序2然后读取的文件。我已经按照各种例子说明了如何安全地做到这一点,但仍然有一个恼人的问题。以下代码在很大程度上有效,但仅限于system.out
之后的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 :(得分:2)
您的代码有竞争条件。当您致电OutputGobbler
时,fos.close()
可能会或可能不会完成吞噬流程的输出。 println
将此线程放慢到足以让gobbler有时间完成处理输出的输出。
在关闭文件之前,必须确保OutputGobbler
已完成将所有输出传输到文件。
答案 1 :(得分:0)
你确定问题出在waitFor()吗?
我认为问题在于刷新外部命令的OutputStream,这解释了为什么System.out.println()修复了这个问题。尝试在waitFor()返回后执行显式的System.out.flush()。
来自Process javadoc:“创建的子进程没有自己的终端或控制台。所有标准的io(即stdin,stdout,stderr)操作都将通过三个流重定向到父进程(getOutputStream(),getInputStream( ),getErrorStream())。“