我遇到了一个奇怪的问题。我已经多次使用进程构建器从程序中调用可执行文件,但之前从未遇到过。出于调试目的,我创建了一个方法,将可执行文件的输出打印到System.out。一切正常,我的程序很好地导出了我运行的所有测试GIF。
当需要为1000多个GIF正确运行此程序时,我注释掉了打印输出方法以提高性能。一旦整个程序运行,我回来发现exportGif不起作用。该程序运行没有错误,但调用该进程根本没有按预期导出gif。
在打印输出方法中隔离行之后,似乎代码的决定位是reader.readLine()
。为什么会这样呢?可执行文件应该已经运行了,调试方法应该只在事后读取输出流,对吗?我不想每次循环它的输出流,因为它会导致程序显着减慢。
private void printProcessOutput(Process process){
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
try{
while ( (line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
}catch(IOException e){
e.printStackTrace();
}
System.out.println(builder.toString());
}
private void exportGIF(String dirPath) throws IOException {
List<String> lines = Arrays.asList("/Users/IdeaProjects/MasterFormat/MasterFormat-Java/MasterFormat/timMaster_4.1.png \"{200.0,467.0}\"");
Path headImageFile = Paths.get(System.getProperty("user.dir") + File.separator + "headImageInfo.txt");
Files.write(headImageFile, lines, Charset.forName("UTF-8"));
String templatePath = dirPath + File.separator + "template.mp4";
String outputPath = dirPath + File.separator;
String headImagePath = headImageFile.toString();
String gifExportExecPath = "/Users/IdeaProjects/MasterFormat/MasterFormat-Java/MasterFormat/GIFExport";
Process process = new ProcessBuilder(gifExportExecPath, "-s", templatePath, "-o", outputPath, "-h", headImagePath).start();
printProcessOutput(process);
Files.delete(headImageFile);
}
修改
我应该补充一点。我注意到当我注释掉调试方法时,它会在不到十分钟的时间内完成所有1000多次迭代,但是,当然gifs不会导出(可执行文件没有运行......?不确定)。
当我包含打印输出方法时,它要慢得多。我试着在一夜之间运行它但在183次迭代后它被卡住了。我试过分析,看它是否引起了一些颠簸,但GC似乎运行正常。
答案 0 :(得分:2)
您需要使用Process的输出,否则它可能会挂起。所以你不能评论printProcessOutput(process);
。相反,注释掉实际打印的行:
try{
while ( (line = reader.readLine()) != null) {
//builder.append(line);
//builder.append(System.getProperty("line.separator"));
}
} catch(IOException e){
e.printStackTrace();
}
//System.out.println(builder.toString());
我通常使用这种方法,它也重定向错误流:
public static void runProcess(ProcessBuilder pb) throws IOException {
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
//System.out.println(line);
}
}