Gibt es in Java ein Command Line binding?

Also, ich muss ein Konsolenfester öffnen, dann ein anderes Programm und dann auf dessen Ausgabe warten (das kann bis zu 30 Sekunden dauern). System.console() und Runtime.getRuntime().exec() eignet sich nur bedingt dafür, weil es A hyper-kompliziert ist, und B nicht event-basiert ist. Wüsstet ihr da etwas?

Das sollte man sowieso nicht mehr verwenden, aktuell ist ProcessBuilder (aber das schon seit Java 7)

https://www.mkyong.com/java/java-processbuilder-examples/

Ist auch ganz interessant… Evtl. kannst du dir da etwas heraus picken…

https://www.baeldung.com/java-9-process-api

Steven

1 Like

Ja Danke an alle! Mit dem ProcessBuilder klappt es super. (Bis auf dass es noch nicht anhält.)

private static void readUntilEnd(BufferedReader i) {
	try {
		String l = null;
		while ((l = i.readLine()) != null ) {
			System.out.println(l);
		}
	} catch (IOException e) {
		e.printStackTrace();
	}
}

private static Future<String> readParallelUntil(BufferedReader i, String til) {
	ExecutorService s = Executors.newSingleThreadExecutor();
	Future<String> f = s.submit(() -> {
		String l = null;
		try {
			while (!(l = i.readLine()).startsWith(til)) {
				System.out.println(l);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return l;
	});
	return f;
}

private static void println(PrintWriter o, String s) {
	o.println(s);
	o.flush();
}

public static void main(String[] args) throws Exception {
	ProcessBuilder b = new ProcessBuilder("C:\\Users\\...\\Downloads\\stockfish-10-win\\Windows\\stockfish_10_x64.exe");
	Process p = b.start();
	PrintWriter o = new PrintWriter(p.getOutputStream());
	BufferedReader i = new BufferedReader(new InputStreamReader(p.getInputStream()));

	Future<String> f = readParallelUntil(i, "bestmove");
	println(o, "position fen rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1");
	println(o, "go movetime 10000");
	System.out.println(f.get());

	f = readParallelUntil(i, "bestmove");
	println(o, "position fen 8/8/8/2k5/4K3/8/8/8 w");
	println(o, "go movetime 10000");
	System.out.println(f.get());

	println(o, "quit");
	readUntilEnd(i);
}

Was meinst du mit „Bis auf dass es noch nicht anhält“?

Steven

Mm, jetzt auf das Beispiel bezogen? Das cli program wird mit „quit“ beendet, die Streams schließen sich aber nicht, und somit das Programm auch nicht, also sie hält nicht an.

Ja, das liegt an zwei Dingen:

  1. Du wartest nicht darauf, dass von den Futures was zurück kommt. Dein Programm läuft weiter zu quit und damit ist die main-methode fertig während parallel eben noch der andere Thread rennt
  2. Solange der andere Thread läuft und kein Daemon-thread ist, solange bleibt rennt auch deine Applikation.

Füge da mal noch nen ProcessHandler dran:
ProcessHandle processHandle = p.toHandle();
…und mit destroy() kannste deinen gestarteten Task beenden:
processHandle.destroy();

Steven :slight_smile: