2008-09-13 16 views
28

JavaのProcessBuilderクラスを使用してプロセスを開始すると、JavaのInputStreamsおよびOutputStreamsという標準の標準入出力ストリームと標準エラーストリームにフルアクセスできます。しかし、私はこれらのストリームをSystem.in,System.out、およびSystem.errにシームレスに接続する方法を見つけることができません。Javaで継承されたstdin/stdout/stderrを使用したプロセスの開始6

redirectErrorStream()を使用して、サブプロセスの標準出力と標準エラーを含む単一のInputStreamを取得し、それをループして標準出力から送信することはできますが、その方法を見つけることができず、私がC system()呼び出しを使用した場合、ユーザーがプロセスに入力することができます。

これは、Java SE 7が出てきたときに表示されます。今すぐ回避策があるのだろうかと思っています。ボーナスは、子プロセスのisatty()の結果がリダイレクトを実行した場合に発生します。

+0

申し訳ありません。 – jjnguy

+0

問題ありません。 (私はあなたに、途中であなたを落とした人ではなかった) –

+0

こんにちは、私に投票してくれない人に感謝します。そして、私に下降しないようにジョンに感謝します。 – jjnguy

答えて

15

アウトストリーム、エラーストリーム、および入力ストリームをシステムバージョンにコピーする必要があります。これを行う最も簡単な方法はCommons IOパッケージのIOUtilsクラスを使用することです。 copy methodは必要なものに見えます。コピーメソッドの呼び出しは別々のスレッドにする必要があります。

// Assume you already have a processBuilder all configured and ready to go 
final Process process = processBuilder.start(); 
new Thread(new Runnable() {public void run() { 
    IOUtils.copy(process.getOutputStream(), System.out); 
} }).start(); 
new Thread(new Runnable() {public void run() { 
    IOUtils.copy(process.getErrorStream(), System.err); 
} }).start(); 
new Thread(new Runnable() {public void run() { 
    IOUtils.copy(System.in, process.getInputStream()); 
} }).start(); 
+4

かなり。 IOUtils.copyはInputStreamを最初の引数として取るので、getOutputStreamでは動作しません。 IOUtils.copy(process.getInputStream()、System.out)です。 getOutputStreamは実際にプロセスの入力にパイプするので、ちょっと混乱します。 – Eelco

+0

この構造は正しく見えますが、IOUtilsへのパラメータが逆戻りしているようです。 process.getInputStream()は、stdoutにパイプする必要があります(ええと、それは後方に発音します)。だから、この構造がうまくいくように見えますが、IOUtilsの呼び出しは間違っているように見えますが、今はちょっと混乱しています... – titania424

+1

間違っています。親と子の入出力ストリーム間のちょうど**パイプ**データは**継承しません**。例えば、Javaコマンドが端末(C isatty()== true、System.console()!= null)上で起動されたとしても、子は端末で実行されているとは見なされません。パイプです。ターミナルで実行されたときに、(ほとんどの)プログラムが異なる動作をするため、これは重要です。 Java 7のProcessBuilder.Redirect.INHERITはこの点で正しく動作します。 – Tobia

13

コンパイルし、コモンズIOを使用する必要はありませんジョンの答えのバリエーション:以下を使用System.inについて

private static void pipeOutput(Process process) { 
    pipe(process.getErrorStream(), System.err); 
    pipe(process.getInputStream(), System.out); 
} 

private static void pipe(final InputStream src, final PrintStream dest) { 
    new Thread(new Runnable() { 
     public void run() { 
      try { 
       byte[] buffer = new byte[1024]; 
       for (int n = 0; n != -1; n = src.read(buffer)) { 
        dest.write(buffer, 0, n); 
       } 
      } catch (IOException e) { // just exit 
      } 
     } 
    }).start(); 
} 
+0

System.inの質問には答えません。 – solotim

+0

なぜパイプ(System.in、process.getOutputStream());動作していないようですか? –

3

pipein()の代わりに、ここで

は、基本的なコードですpipe()

pipein(System.in, p.getOutputStream()); 

実装:

private static void pipein(final InputStream src, final OutputStream dest) { 

    new Thread(new Runnable() { 
     public void run() { 
      try { 
       int ret = -1; 
       while ((ret = System.in.read()) != -1) { 
        dest.write(ret); 
        dest.flush(); 
       } 
      } catch (IOException e) { // just exit 
      } 
     } 
    }).start(); 

} 
+0

これは動作しません。 –

関連する問題