「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > ProcessBuilder のノンブロッキング出力リダイレクトを実現するにはどうすればよいですか?

ProcessBuilder のノンブロッキング出力リダイレクトを実現するにはどうすればよいですか?

2024 年 12 月 13 日に公開
ブラウズ:584

How to Achieve Non-Blocking Output Redirection for ProcessBuilder?

ProcessBuilder のノンブロッキング出力リダイレクト

Java でプロセスを実行するために、ProcessBuilder は便利なアプローチを提供します。ただし、実行されたプロセスの stdout ストリームと stderr ストリームを System.out に非同期にリダイレクトする必要がある場合に問題が発生します。

Thread

を使用した非同期リダイレクトの 1 つの一般的な方法これには、stdOut からの読み取りと System.out への書き込みを継続的に行う新しいスレッドを手動で生成することが含まれます。このアプローチは機能しますが、追加のスレッド管理オーバーヘッドが発生します。

ProcessBuilder.inheritIO を使用したエレガントなソリューション

Java 7 以降が利用可能な場合、ProcessBuilder はよりシンプルでエレガントなソリューションを提供します。解決策: ProcessBuilder.inheritIO。このメソッドは、親 Java プロセスの標準 I/O ストリームを継承するようにサブプロセスの標準 I/O ストリームを設定します。

inheritIO の使用は簡単です:

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