2011-10-13 43 views
5

私はそれではなく、コマンドが完了するのを待っているの利用可能である限り実行されているシェルコマンドの出力を取得したいのですが。私のコードは、新しいスレッドのJavaのRuntime.exec()非同期出力

Process proc = Runtime.getRuntime().exec("/opt/bin/longRunning"); 
InputStream in = proc.getInputStream(); 
int c; 
while((c = in.read()) != -1) { 
    MyStaticClass.stringBuilder.append(c); 
} 

で実行されてこれに伴う問題は、/ opt/binに/ longRunningで私のプログラムは、入力ストリームが割り当てられ、読まれる前に完了することがあるということです。これを非同期的に行う良い方法はありますか?私の目標は、AJAXリクエストは現在の値MyStaticClass.stringBuilder.toString() 秒ごとに返すことです。

私はFYI、Java 5の上こだわっています。

ありがとうございます! W

+0

おかげですべてを! Apache CommonsのExecは、私が行った方法です。 @Paul Cager、素晴らしいアイデアを提供しました。呼び出されたスクリプトは、実際にパイプされてブロックされていることを検出していました。しかし、あなたがRuntime.execから取得したストリームは同期されているので、それを読み込もうとするとブロックしています。 – wmarbut

答えて

7

Apache Common Execで試してみてください。非同期にプロセスを実行し、その出力をスレッドに「ポンプ」する機能を備えています。詳細

1

Runtime.getRuntime()。execが終了するコマンドのない待ちをして、あなたはすぐに出力を取得する必要があります。コマンドはターミナルではなくパイプに書き込んでいることを知っているので、出力がバッファされている可能性がありますか?

1

ためJavadocを確認し、新しいスレッドで読書を入れて:

new Thread() { 
    public void run() { 
     InputStream in = proc.getInputStream(); 
     int c; 
     while((c = in.read()) != -1) { 
      MyStaticClass.stringBuilder.append(c); 
     } 
    } 
}.start(); 
+0

私はここで少しばかげているかもしれませんが、どのようにしてスレッドから変数cを得ることができますか?しかも、文字列ではないはずですか? –

2

は、あなたが呼び出しているプログラムを書きましたか?もしそうなら、書いた後で出力を洗い流してみてください。テキストがバッファーに詰まり、Javaプログラムに到達しない可能性があります。

私はこれを行うには、このコードを使用し、それが動作:

Runtime runtime = Runtime.getRuntime(); 
    Process proc = runtime.exec(command); 
    BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); 

    while (true) { 

     // enter a loop where we read what the program has to say and wait for it to finish 
     // read all the program has to say 
     while (br.ready()) { 
      String line = br.readLine(); 
      System.out.println("CMD: " + line); 
     } 

     try { 
      int exitCode = proc.exitValue(); 
      System.out.println("exit code: " + exitCode); 
      // if we get here then the process finished executing 
      break; 
     } catch (IllegalThreadStateException ex) { 
      // ignore 
     } 

     // wait 200ms and try again 
     Thread.sleep(200); 

    } 
+0

BufferedReader.ready()はBufferedReader.readLine()の状態もカバーしていますか?このドキュメントでは、ready()はread()を使用できることを示していますが、readLine()はおそらくread()操作の2つになります。 – bcause

+0

あなたはそうです、それはブロックされ、サブプロセスが終了するまでこのループに留まります。これは私の意見では正しいです。このプログラムが実行を終了する前に何か別の処理をしたい場合は、このコードを別のスレッドに入れ、別のスレッドで別のスレッドを実行します。私は、あなたがネットワークソケットで行うことができるように、ProcessからNonStreamを返すようにInputStreamを返す方法は見当たりません。その場合、ストリームから読み込もうとするとタイムアウト例外がスローされます。 –

0

試してみてください。

try { 
     Process p = Runtime.getRuntime().exec("/opt/bin/longRunning"); 
     BufferedReader in = new BufferedReader( 
            new InputStreamReader(p.getInputStream())); 
     String line = null; 
     while ((line = in.readLine()) != null) { 
     System.out.println(line); } 
関連する問題