首页 > Java > java教程 > 如何实现ProcessBuilder的非阻塞输出重定向?

如何实现ProcessBuilder的非阻塞输出重定向?

Barbara Streisand
发布: 2024-11-28 05:57:09
原创
254 人浏览过

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中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板