擬似コードでは、これが私がしていることです:
Process proc = runtime.exec(command);
processOutputStreamInThread(proc.getInputStream());
processOutputStreamInThread(proc.getErrorStream());
proc.waitFor()
ただし、processOutputStreamInThread
出力が表示されない場合と表示される場合があります。大まかに言って、このメソッドはBufferedInputStream
コマンドの出力を作成し、それをロガーに送信します。
私が見ているものに基づいて、とによってcommand
供給されるストリームにすべての出力をダンプする必要はないので、ストリームを空にする必要はないと推測しています。getInputStream()
getErrorStream()
私の試験の結果は次の質問です:
(1)java.lang.ProcesswaitFor()
では、実行されたプログラムの出力が返される前に読み取られている必要がありますか?
ドキュメントには次のように記載されています。
Process
このオブジェクトによって表されるプロセスが終了するまで、必要に応じて現在のスレッドを待機させます。サブプロセスがすでに終了している場合、このメソッドはすぐに戻ります。サブプロセスがまだ終了していない場合、呼び出し元のスレッドはサブプロセスが終了するまでブロックされます。
(2)ストリームはどのような条件下で提供されgetInputStream
、getErrorStream
閉じる必要がありますか、および/または自動的に閉じられますか?
ドキュメントには次のように記載されています。
サブプロセスのエラーストリームを取得します。ストリームは、このProcessオブジェクトによって表されるプロセスのエラー出力ストリームからパイプされたデータを取得します。
実装上の注意:入力ストリームをバッファリングすることをお勧めします。
あるユーザーは、自分でストリームを閉じなければならなかったと報告していますが、少なくとも一部の時間は、そうしようとするとストリームがすでに閉じられていることを示す例外が発生します。
編集:に変更さgetOutputStream
れgetInputStream
、現在は上にあります。
解決策:問題は、場合によっては、出力ストリームの処理に使用されるスレッドが、非常に短期間のプロセスが完了するまで実行されず、入力ストリームからデータが得られないことでした。 waitFor
実行されたプログラムの出力を待つことはしませんでした。むしろ、出力が収集される前に、プログラムが実行されて終了しました。
スレッドを使用したのは、標準エラーと標準出力でどれだけの出力が得られるかわからないためです。どちらか一方だけがデータを使用できる場合は、どちらか一方をブロックせずに、両方を同時に処理できるようにしたかったのです。しかし、私のスレッドは実行されたプログラムの出力を一貫して読み取ることができないため、それは解決策ではありません。
私の最終的なコードは次のようになりました。
ProcessBuilder pb = new ProcessBuilder(cmdargs);
pb.redirectErrorStream(true);
Process proc = pb.start();
processOutputStream(proc.getInputStream());
proc.waitFor()