Heim >Java >javaLernprogramm >Wie behandelt man Eingabe-/Ausgabeströme in Java-Prozessen richtig, um Blockierungen zu vermeiden?
Java-Prozess mit Eingabe-/Ausgabestream
Beachten Sie den folgenden Codeausschnitt:
Scanner scan = new Scanner(System.in); Process process = Runtime.getRuntime().exec("/bin/bash"); OutputStream stdin = process.getOutputStream(); InputStream stderr = process.getErrorStream(); InputStream stdout = process.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(stdout)); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stdin)); String input = scan.nextLine(); input += "\n"; writer.write(input); writer.flush(); input = scan.nextLine(); input += "\n"; writer.write(input); writer.flush(); while ((line = reader.readLine()) != null) { System.out.println("Stdout: " + line); } input = scan.nextLine(); input += "\n"; writer.write(input); writer.close(); while ((line = reader.readLine()) != null) { System.out.println("Stdout: " + line); }
Dieser Code ermöglicht es Ihnen um einen Befehl in die Bash-Shell einzugeben und seine Ausgabe zu erhalten. Nach der ersten Eingabe und Ausgabe führen nachfolgende Eingaben jedoch nicht zur erwarteten Ausgabe.
Warum das passiert
Das Problem entsteht, weil der Code nicht richtig verarbeitet wird die End-of-File-Bedingung (EOF) für die Standardausgabe des Bash-Prozesses. Die Schleife while ((line = readLine()) != null) wird nur beendet, wenn der Prozess beendet wird. Das bedeutet, dass die Schleife auf unbestimmte Zeit blockiert, wenn keine weitere Ausgabe vom Prozess erfolgt.
Vorgeschlagene Lösung – ProcessBuilder und --EOF-- Handhabung
Berücksichtigen Sie Folgendes, um dieses Problem zu beheben Änderungen:
ProcessBuilder builder = new ProcessBuilder("/bin/bash"); builder.redirectErrorStream(true); Process process = builder.start();
Durch die Verwendung von ProcessBuilder anstelle von Runtime.getRuntime().exec() können Sie den Standardfehler des Bash-Prozesses auf seine Standardausgabe umleiten und so sicherstellen, dass Sie nur einen Eingabestream benötigen.
Darüber hinaus kann der Code geändert werden, um ein spezielles Trennzeichen, --EOF--, zu senden, um das Ende der Ausgabe eines Befehls zu signalisieren. Dadurch kann der Code die Ausgabe zuverlässig von mehreren Befehlen trennen.
while (scan.hasNext()) { String input = scan.nextLine(); if (input.trim().equals("exit")) { // Putting 'exit' amongst the echo --EOF--s below doesn't work. writer.write("exit\n"); } else { writer.write("((" + input + ") & echo --EOF-- || echo --EOF--)\n"); } writer.flush(); line = reader.readLine(); while (line != null && !line.trim().equals("--EOF--")) { System.out.println("Stdout: " + line); line = reader.readLine(); } }
Mit diesen Änderungen verarbeitet der Code zuverlässig mehrere Befehle und deren Ausgabe und stellt so die gewünschte Funktionalität bereit.
Das obige ist der detaillierte Inhalt vonWie behandelt man Eingabe-/Ausgabeströme in Java-Prozessen richtig, um Blockierungen zu vermeiden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!