ProcessBuilderの使い方
JavaDoc読んでもよく分かんなくてはまった><。4,5時間これに嵌り続けたので晒しておこう。間違ってる点は指摘してくださいませ。
OvOðÀsµÄÊðæ¾·é(Java}X^[)のページを参考にしました。(ありがとうございます!)ポイントは以下の通り。
- 今回のはWindows XP上の話で他のOSの事はとりあえず横において置いてます。
- 1コマンドの実行は1Processで。
- ProcessBuilder#command(String...)は "コマンド名","引数1","引数2"...と言うように指定する。(JavaDocから類推すると複数コマンド実行できるように見えるじゃんか><)
- 環境変数はSystem.getenv()からコピーしてくれるような期待をさせてくれるJavaDocだけど、そんなことしてあげないから!っていう感じ。Windows版JREは意外にツンなのか。
- という事で、環境変数PATHも自前で設定しなければならないようだ。
- でもC:\Windows\System32にはパスが通っているらしい。
- 環境変数の設定はProcessBuilder#environment().put("PATH",環境変数で指定したいパス);
- 環境変数で指定したいパスはもちろん「;」で区切って複数指定できるらしい。
- Process#getInputStream()やProcess#getErrorStream()はもちろん同一スレッドで受け取ってたら「まとめて出力」しか出来ないので、ストリームで扱う意味がなくなってまう。参考リンク先のようにThreadを作るのが正解。
- でもStringWriter#printlnを使っちゃうのは速度的に良いのかもわかんないけど、System.outやSystem.errに直接流し込んじゃう方が素のコンソールに近い動きをするはずだからいいんじゃなかろうか。
サンプルコードのCatcherをいじってみる。
class Catcher extends Thread { Reader in; PrintWriter out; public Catcher(Reader in,PrintWriter out) { this.in = in; this.out = out; } public void run() { int c; try { while ((c = in.read()) != -1) { out.write((char)c); } } catch (IOException e) { e.printStackTrace(); } } }
こうしておくとこんな感じでストリームを監視するスレッドを作成できる。
new Catcher(p.getInputStream(),System.out); new Catcher(p.getErrorStream(),System.err);
繰り返しますが、変なところはじゃんじゃんつっこんで下さい!よく分からんの。ProcessBuilderは。