」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 如何實作ProcessBuilder的非阻塞輸出重新導向?

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

發佈於2024-12-13
瀏覽:562

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 。此方法將子程序的標準 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 啟動的進程的非阻塞輸出重定向。

最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3