見出し画像

役に立つのかわからない: Javaでの「stdinの差し替え」

Javaでコードを書いているのですが、stdinからデータを受け取るようなプログラムを受け取るmain()メソッド持ちのクラス(勉強の中でよく作るアレ)に対して、データの入力を自動化させようという流れの話です。

普通に考えれば、

$ mvn exec:java -Dexec.mainClass=Callee

とでも呼ぶところであり、ここ入力ファイルを付けるのであれば、

$ mvn exec:java -Dexec.mainClass=Callee < input.txt 

とでもすれば済む話と思います。でも入力そのものをプログラム的に差し替えたいときで、Javaの中で済ませたいと思ったらどうするんだろうと思って少しだけあがいてみました…

public class Callee {
	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		try(var in = new Scanner(System.in))  {
			System.out.print("in --> ");
			var n = in.nextInt();
			System.out.println("out --> " + n);
		}
	}
}
public class Caller {
	public static void main(String[] args) {
		// TODO 自動生成されたメソッド・スタブ
		try {
			Callee.main(args);
		} catch (IOException e) {
			// TODO 自動生成された catch ブロック
			e.printStackTrace();
		}
	}
}

と、Eclipseのテンプレート等を使いつつ作ってみました。

ここで、System階層のメソッドを漁っていたのですが、setInというメソッドにより、読み込み先となるストリームを差し替えるということがサポートされていたのでした。ということで、

			InputStream swappedIn =
					new BufferedInputStream(
							new FileInputStream("small.txt"));
			System.setIn(swappedIn);
			Callee.main(args);

​

とすれば、キーボードの代わりにsmall.txtを入力に渡せるということですね。とはいえこれではまだ終わりませんよね。

small.txtを本番で使う前に作成したり、いっそのこと任意のデータストリームを実行中にこさえて渡せるようになればとか夢が広がるところなのですが、ここまで苦労するなら、普通にパイプやリダイレクションで入れてあげれば済む話だったかと思います。あぁ、なんて無駄なところに時間を費やしてしまったんだよおい…

この記事が気に入ったらサポートをしてみませんか?