私はここで頭がいっぱいです。これは単純なことだと確信しており、Java とストリームの理解に大きな穴がある可能性が高いです。非常に多くのクラスがあるため、API を調べて、多数の入出力ストリームをいつどのように使用するかを把握するのに少し圧倒されていると思います。
apache commons ライブラリの存在を知ったばかりで (Java の自己学習は失敗します)、現在、Runtime.getRuntime().exec の一部を変換して commons を使用しようとしています - exec. 6 か月に 1 回発生するこの問題の一部はすでに修正されており、exec のスタイルの問題は解消されています。
このコードは perl スクリプトを実行し、スクリプトの実行中にスクリプトからの stdout を GUI に表示します。
呼び出しコードは、swingworker の内部にあります。
pumpStreamHandler の使用方法がわかりません... とにかく古いコードは次のとおりです。
String pl_cmd = "perl script.pl"
Process p_pl = Runtime.getRuntime().exec( pl_cmd );
BufferedReader br_pl = new BufferedReader( new InputStreamReader( p_pl.getInputStream() ) );
stdout = br_pl.readLine();
while ( stdout != null )
{
output.displayln( stdout );
stdout = br_pl.readLine();
}
これは、ずっと前に完全には理解できなかったコピーペーストコードに対して得られるものだと思います。上記はプロセスを実行していると仮定し、出力ストリームを取得して(「getInputStream」を介して)、バッファリングされたリーダーに配置し、バッファが空になるまでそこでループします。
私が得られないのは、ここで「waitfor」スタイルのコマンドが必要ない理由です? バッファが空になり、ループを終了し、プロセスがまだ進行している間に続行する時間がある可能性はありませんか? 実行すると、そうではないようです。
いずれにせよ、私は commons exec を使用して同じ動作を得ようとしています。
DefaultExecuteResultHandler rh = new DefaultExecuteResultHandler();
ExecuteWatchdog wd = new ExecuteWatchdog( ExecuteWatchdog.INFINITE_TIMEOUT );
Executor exec = new DefaultExecutor();
ByteArrayOutputStream out = new ByteArrayOutputStream();
PumpStreamHandler psh = new PumpStreamHandler( out );
exec.setStreamHandler( psh );
exec.setWatchdog( wd );
exec.execute(cmd, rh );
rh.waitFor();
pumpstreamhandler が何をしているかを把握しようとしています。これは exec オブジェクトからの出力を取得し、OutputStream に perl スクリプトの stdout/err からのバイトを入力します。
もしそうなら、どのように上記の動作を取得して、出力を行ごとにストリーミングしますか? 例では、最後に out.toString() を呼び出すことを示していますが、スクリプトの実行が完了すると、スクリプトからのすべての出力のダンプが得られると思いますか? 行ごとに実行されているときに出力が表示されるようにするにはどうすればよいですか?
------------ 今後の編集 ----------------------
Google経由でこれを見つけて、同様にうまく機能します:
public static void main(String a[]) throws Exception
{
ByteArrayOutputStream stdout = new ByteArrayOutputStream();
PumpStreamHandler psh = new PumpStreamHandler(stdout);
CommandLine cl = CommandLine.parse("ls -al");
DefaultExecutor exec = new DefaultExecutor();
exec.setStreamHandler(psh);
exec.execute(cl);
System.out.println(stdout.toString());
}