在Java 6中使用继承的stdin / stdout / stderr启动进程
时间:2020-03-05 18:52:39 来源:igfitidea点击:
如果我通过Java的ProcessBuilder类启动一个进程,则可以完全访问该进程的标准输入,标准输出和标准错误流,如Java" InputStreams"和" OutputStreams"。但是,我找不到将这些流无缝连接到" System.in"," System.out"和" System.err"的方法。
可以使用redirectErrorStream()
来获取包含子进程的标准输出和标准错误的单个InputStream,然后循环遍历并通过我的标准输出发送它,但是我找不到办法让它用户输入流程,就像我使用Csystem()
调用一样。
Java SE 7发行时这似乎是可能的我只是想知道现在是否有解决方法。如果子进程中" isatty()"的结果进行了重定向,则奖励积分。
解决方案
回答
我们将需要将Process输出,err和输入流复制到System版本。最简单的方法是使用Commons IO包中的IOUtils类。复制方法看起来就是我们所需要的。复制方法调用将需要在单独的线程中。
这是基本代码:
// Assume you already have a processBuilder all configured and ready to go final Process process = processBuilder.start(); new Thread(new Runnable() {public void run() { IOUtils.copy(process.getOutputStream(), System.out); } } ).start(); new Thread(new Runnable() {public void run() { IOUtils.copy(process.getErrorStream(), System.err); } } ).start(); new Thread(new Runnable() {public void run() { IOUtils.copy(System.in, process.getInputStream()); } } ).start();
回答
John答案的一种变体,可以编译,不需要我们使用Commons IO:
private static void pipeOutput(Process process) { pipe(process.getErrorStream(), System.err); pipe(process.getInputStream(), System.out); } private static void pipe(final InputStream src, final PrintStream dest) { new Thread(new Runnable() { public void run() { try { byte[] buffer = new byte[1024]; for (int n = 0; n != -1; n = src.read(buffer)) { dest.write(buffer, 0, n); } } catch (IOException e) { // just exit } } }).start(); }