„Wenn ein Arbeiter seine Arbeit gut machen will, muss er zuerst seine Werkzeuge schärfen.“ – Konfuzius, „Die Gespräche des Konfuzius. Lu Linggong“
Titelseite > Programmierung > Wie erreicht man eine nicht blockierende Ausgabeumleitung für ProcessBuilder?

Wie erreicht man eine nicht blockierende Ausgabeumleitung für ProcessBuilder?

Veröffentlicht am 13.12.2024
Durchsuche:680

How to Achieve Non-Blocking Output Redirection for ProcessBuilder?

Nicht blockierende Ausgabeumleitung für ProcessBuilder

Um Prozesse in Java auszuführen, bietet ProcessBuilder einen praktischen Ansatz. Die Herausforderung entsteht jedoch, wenn wir die stdout- und stderr-Streams des ausgeführten Prozesses asynchron an System.out umleiten müssen.

Asynchrone Umleitung mit Thread

Eine gängige Methode Dazu gehört das manuelle Erzeugen eines neuen Threads, der kontinuierlich von stdOut liest und in System.out schreibt. Dieser Ansatz ist zwar funktionsfähig, erzeugt jedoch zusätzlichen Aufwand für die Thread-Verwaltung.

Elegante Lösung mit ProcessBuilder.inheritIO

Wenn Java 7 oder höher verfügbar ist, bietet ProcessBuilder eine einfachere und elegantere Lösung Lösung: ProcessBuilder.inheritIO. Diese Methode legt die Standard-E/A-Streams des Unterprozesses so fest, dass sie die des übergeordneten Java-Prozesses erben.

Die Verwendung von inheritIO ist unkompliziert:

Process p = new ProcessBuilder().inheritIO().command("command1").start();

Alternative für frühere Java-Versionen Versionen

Für Java-Versionen vor 7 kann die folgende Implementierung verwendet werden:

import java.io.*;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class NonBlockingOutputRedirection {
    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        Process p = Runtime.getRuntime().exec("cmd /c dir");
        inheritIO(p.getInputStream(), System.out, executorService);
        inheritIO(p.getErrorStream(), System.err, executorService);
    }

    private static void inheritIO(final InputStream src, final PrintStream dest, ExecutorService executorService) {
        executorService.execute(() -> {
            Scanner scanner = new Scanner(src);
            while (scanner.hasNextLine()) {
                dest.println(scanner.nextLine());
            }
        });
        executorService.shutdown();
    }
}

Vorteile dieser Methode

Diese Methode bietet mehrere Vorteile:

  • Asynchron: Die Ausgabeumleitung erfolgt in den Hintergrund, wodurch der Hauptthread freigegeben wird.
  • Automatische Thread-Beendigung: Wenn der Unterprozess Wenn der Vorgang abgeschlossen ist, werden die für die Ausgabeumleitung verantwortlichen Threads aufgrund des Dateiendes in den Eingabestreams automatisch beendet.

Im Allgemeinen wird ProcessBuilder.inheritIO in Java 7 oder höher oder die alternative Implementierung früher verwendet Versionen bietet eine saubere und effiziente Möglichkeit, eine nicht blockierende Ausgabeumleitung für mit ProcessBuilder gestartete Prozesse zu erreichen.

Neuestes Tutorial Mehr>

Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.

Copyright© 2022 湘ICP备2022001581号-3