首頁 >Java >java教程 >如何實作ProcessBuilder的非阻塞輸出重新導向?

如何實作ProcessBuilder的非阻塞輸出重新導向?

Barbara Streisand
Barbara Streisand原創
2024-11-28 05:57:09192瀏覽

How to Achieve Non-Blocking Output Redirection for ProcessBuilder?

ProcessBuilder 的非阻塞輸出重定向

為了在 Java 中執行進程,ProcessBuilder 提供了一個方便的方法。然而,當我們需要將執行進程的 stdout 和 stderr 流非同步重新導向到 System.out 時,就會出現挑戰。

使用線程非同步重定向

一種常用方法涉及手動產生一個新線程,該線程不斷從 stdOut 讀取並寫入 System.out。雖然有效,但這種方法會產生額外的執行緒管理開銷。

使用ProcessBuilder.inheritIO 的優雅解決方案

如果Java 7 或更高版本可用,ProcessBuilder 提供更簡單、更優雅的解決方案:ProcessBuilder. inheritIO。此方法將子程序的標準 I/O 流設定為繼承父 Java 程序的標準 I/O 流。

使用繼承IO 很簡單:

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

早期 Java 版本的替代方案

對於 7 之前的 Java版本,可以採用以下實作使用:

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

此方法的優點

此方法有幾個優點:

  • 非同步:輸出重定向發生在後台,釋放了主要的
  • 自動執行緒終止:當子進程完成時,負責輸出重定向的執行緒將由於輸入流上的檔案結尾而自動終止。

總體而言,在Java 7 或更高版本中使用ProcessBuilder.inheritIO 或早期版本的替代實現,提供了一種乾淨高效的方法來實現非阻塞使用ProcessBuilder 啟動的進程的輸出重定向。

以上是如何實作ProcessBuilder的非阻塞輸出重新導向?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn