2017-05-05 8 views
2

私は奇妙な問題に遭遇しました。私はプロセスビルダーをプログラムから実行可能ファイルを呼び出すために数回使用しましたが、これまでにこれまでに遭遇したことはありません。デバッグの目的のために、実行可能ファイルの出力をSystem.outに出力するメソッドを作成しました。すべて正常に動作し、私のプログラムはうまくいけば、実行したテスト用のgifをすべてエクスポートしました。出力を印刷しない限りプロセスは実行されません+ Processbuilder

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); 
    } 

EDIT

一つ。私は、デバッグ方法をコメントアウトすると、10分以内に1000回以上の繰り返しをすべて処理することに気付きました。しかし、もちろんGIFはエクスポートされません(実行ファイルは実行されません...?

私がプリントアウトメソッドをインクルードすると、処理速度がかなり遅くなります。私は一晩中実行しようとしましたが、183回の反復の後に固まってしまいました。私はそれがいくつかのスラッシングを引き起こしていたかどうかを見るためにプロファイリングを試みましたが、GCは正常に動作するようです。

+1

手段「プログラムはエラーなしで走った」:私は、一般的にも、エラーストリームをリダイレクトし、このメソッドを使用

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()); 

:代わりに、実際に印刷を行う行をコメントアウトそれは右 "ハングアップ"していない?したがって、ここで私は推測と同じではありません:http://stackoverflow.com/questions/22953760/processbuilder-process-not-running?rq=1 – dbalakirev

答えて

2

プロセスの出力を消費する必要があるか、ハングすることがあります。だから、printProcessOutput(process);をコメントアウトすることはできません。あなたが書く

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); 
    } 
} 
+0

プロセスのJavadocから: "デフォルトでは、作成されたサブプロセスには(標準出力、stdout、stderr)操作はすべて親プロセスにリダイレクトされます[...]ネイティブプラットフォームの中には、標準の入力ストリームと出力ストリームに対して限られたバッファサイズしかないものがあるため、入力ストリームを速やかに書き込むことや、サブプロセスの出力ストリームを読み込むことができないと、サブプロセスがブロックされたり、デッドロックが発生する可能性があります。そう、はい、プロセスは実際に完了するのを待っていて、あなたはerr/outストリームを消費しないメ​​モリリークを得ることができます。 –

関連する問題