java内部からプログラムを起動してプロセス通信をして操作する

javaからrubyを利用したら便利そうだと思って調べてみるとプロセス通信を使えばよさそう。
標準入出力についていまいち理解してなかったけど結構面白いです。


標準入出力をつかったプロセス通信を利用すれば異なる言語同士のよいところを取り入れてさくっとい
ろんなものが作れそうだと思いました。


今回はJava <-> Java間の通信ですがRubyの標準入出力のgetsなどでも通信できます。
実行方法は適当なファイル(Test.javaなど)に保存したあと


javac Test.java
java Main


でできます。修飾氏をつけないと同じパッケージ間同士ならpublic感覚で使えるという利点があるそうです。知らなかったんですがすごい便利。

import java.io.*;

class Main extends Thread {
  void p(Object o) { System.out.println(o); }
  BufferedReader in;
  PrintStream out;

  public void run() { try {
    BufferedReader key = new BufferedReader(new InputStreamReader(System.in));
    for(;;) {
      System.out.print("> ");
      String line = key.readLine();
      if(line == null || line.equals("exit")) { break; }
      out.println(line);
      out.flush();
    }
    key.close();
    out.close();
  } catch(Exception e) { e.printStackTrace(); }}

  Main() { try {
    Process p = new ProcessBuilder("java", "Sub").start();
    in = new BufferedReader(new InputStreamReader(p.getInputStream()));
    out = new PrintStream(p.getOutputStream());
    start();

    p.waitFor();
    
    // ここもスレッドを作ればリアルタイムにサブプロセスからの返事が返ってくる
    for(;;) {
      String line = in.readLine();
      if(line == null) { break; }
      p(line);
    }
    in.close();
    p.destroy();
  } catch(Exception e) { e.printStackTrace(); }}

  public static void main(String[] args) { new Main(); }
}

class Sub {
  void p(Object o) { System.out.println(o); }

  Sub() { try {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    for(;;) {
      String line = in.readLine();
      if(line == null) { break; }
      System.out.println("Sub convert :" + line.toUpperCase());
    }
    in.close();
  } catch(Exception e) { e.printStackTrace(); }}
  public static void main(String[] args) { new Sub(); }
}