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