プロセスの起動
コンソール限定だけども。
後始末とか意外と知られていないようなので。
public class Main { public static void main(String[] args) { try { run("cmd.exe", "/c", "dir", "/s", "\\*.exe"); } catch (Exception e) { e.printStackTrace(); } } public static class Pipe implements Runnable { private InputStream src; private OutputStream dest; public Pipe(InputStream src, OutputStream dest) { this.src = src; this.dest = dest; } @Override public void run() { BufferedReader reader = new BufferedReader(new InputStreamReader(src)); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(dest)); String line = null; try { while ((line = reader.readLine()) != null) { writer.write(line); writer.newLine(); } writer.flush(); } catch (IOException e) { e.printStackTrace(); } } } public static int run(String... cmd) throws Exception { Process process = new ProcessBuilder(cmd).start(); // この3つのリソースは使わなくてもクローズする必要がある InputStream stdout = process.getInputStream(); InputStream stderr = process.getErrorStream(); OutputStream stdin = process.getOutputStream(); // プロセスの標準出力・エラー出力共にバッファリングされており、ある程度溜まると書き込みがブロックされてしまうので、こっちで読み込んでやる必要がある // ただ、プロセスから取得したストリームはプロセスが終了するまで読み込み可能な状態にあるので、プロセスの終了を待機する前に一般的な読み込み処理のループを書いてしまうと終了条件が成立しない // そこで、標準出力・エラー出力からの読み込みは別スレッドで行い、メインのスレッドはプロセスの終了を待機するだけにする Thread outCopyThread = new Thread(new Pipe(stdout, System.out)); Thread errCopyThread = new Thread(new Pipe(stderr, System.err)); outCopyThread.start(); errCopyThread.start(); Exception e = null; try { return process.waitFor(); } catch (Exception ex) { e = ex; } finally { // 個別に後始末を行い、かつエラーが起きたら最初のものをthrowする // もっとマシな書き方が無いものか・・・ try { outCopyThread.join(); } catch (InterruptedException ex) { } try { errCopyThread.join(); } catch (InterruptedException ex) { } try { stdout.close(); } catch (Exception ex) { if (e == null) { e = ex; } else { ex.printStackTrace(); } } try { stderr.close(); } catch (Exception ex) { if (e == null) { e = ex; } else { ex.printStackTrace(); } } try { stdin.close(); } catch (Exception ex) { if (e == null) { e = ex; } else { ex.printStackTrace(); } } process.destroy(); } throw e; } }