Javaから外部プロセスのストリーム(IO)を生成して消費する適切な方法は何ですか?私が知る限り、Javaの入力ストリーム(プロセス出力)は、おそらく制限されたバッファサイズのためにプロセス入力を生成するのと並行してスレッドで消費されるべきです。Java execメソッド、ストリームを正しく処理する方法
しかし最終的にそれらのコンシューマスレッドと同期する必要があるかどうかわからない、またはすべてのプロセス出力が実際に消費されていることを確認するために、プロセスがwaitFor
メソッドで終了するのを待つだけで十分ですか? I.Eは可能です。プロセスが終了しても(出力ストリームを閉じます)、まだストリームのJava側に未読データがありますか? waitFor
は、プロセスがいつ完了したかを実際にどのように知っていますか?問題のプロセスについては、EOF(入力ストリームのJava終了を閉じる)が終了を知らせます。ストリームを処理するために
私の現在のソリューション
public class Application {
private static final StringBuffer output = new StringBuffer();
private static final StringBuffer errOutput = new StringBuffer();
private static final CountDownLatch latch = new CountDownLatch(2);
public static void main(String[] args) throws IOException, InterruptedException {
Process exec = Runtime.getRuntime().exec("/bin/cat");
OutputStream procIn = exec.getOutputStream();
InputStream procOut = exec.getInputStream();
InputStream procErrOut = exec.getErrorStream();
new Thread(new StreamConsumer(procOut, output)).start();
new Thread(new StreamConsumer(procErrOut, errOutput)).start();
PrintWriter printWriter = new PrintWriter(procIn);
printWriter.print("hello world");
printWriter.flush();
printWriter.close();
int ret = exec.waitFor();
latch.await();
System.out.println(output.toString());
System.out.println(errOutput.toString());
}
public static class StreamConsumer implements Runnable {
private InputStream input;
private StringBuffer output;
public StreamConsumer(InputStream input, StringBuffer output) {
this.input = input;
this.output = output;
}
@Override
public void run() {
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line;
try {
while ((line = reader.readLine()) != null) {
output.append(line + System.lineSeparator());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
latch.countDown();
}
}
}
}
}
次され、それはここで、ラッチを使用することが必要である、またはwaitFor
は、すべての出力が既に消費され巻き込むのか?また、出力が終了しない/新しい行が含まれている場合は、readLine
は出力を見逃しているのでしょうか? nullを読み込むプロセスがストリームの終わりを閉じているのですか?ヌルを読み取ることができる他のシナリオはありますか?
ストリームを処理する正しい方法は何ですか、私の例よりも何か良いことができますか?
ありがとうございます。残念ながら、コードはJDK6に準拠している必要があります –
JavaPoolからThreadPoolが存在します。 [Executors](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html)を参照してください。 – kurt