«Если рабочий хочет хорошо выполнять свою работу, он должен сначала заточить свои инструменты» — Конфуций, «Аналитики Конфуция. Лу Лингун»
титульная страница > программирование > Как добиться неблокирующего перенаправления вывода для ProcessBuilder?

Как добиться неблокирующего перенаправления вывода для ProcessBuilder?

Опубликовано 13 декабря 2024 г.
Просматривать:221

How to Achieve Non-Blocking Output Redirection for ProcessBuilder?

Неблокирующее перенаправление вывода для ProcessBuilder

Для выполнения процессов на Java ProcessBuilder предлагает удобный подход. Однако проблема возникает, когда нам нужно асинхронно перенаправить потоки stdout и stderr исполняемого процесса в System.out.

Асинхронное перенаправление с использованием Thread

Один распространенный метод включает в себя создание вручную нового потока, который постоянно читает из stdOut и записывает в System.out. Несмотря на свою функциональность, этот подход создает дополнительные накладные расходы на управление потоками.

Элегантное решение с ProcessBuilder.inheritIO

Если доступна Java 7 или более поздняя версия, ProcessBuilder обеспечивает более простой и элегантный подход. решение: ProcessBuilder.inheritIO. Этот метод устанавливает стандартные потоки ввода-вывода подпроцесса для наследования потоков родительского процесса Java.

Использовать inheritIO очень просто:

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

Альтернатива для более ранних версий Java Версии

Для версий Java до 7 можно использовать следующую реализацию:

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();
    }
}

Преимущества этого метода

Этот метод предлагает несколько преимуществ:

  • Асинхронный: Перенаправление вывода происходит в фон, освобождая основной поток.
  • Автоматическое завершение потока: Когда подпроцесс завершается, потоки, ответственные за перенаправление вывода, автоматически завершаются из-за конца файла во входных потоках.

В целом, использование ProcessBuilder.inheritIO в Java 7 или более поздней версии или альтернативная реализация для более ранних версиях предоставляет простой и эффективный способ неблокирующего перенаправления вывода для процессов, запущенных с помощью ProcessBuilder.

Последний учебник Более>

Изучайте китайский

Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.

Copyright© 2022 湘ICP备2022001581号-3