在Java 6中使用inheritance的stdin / stdout / stderr启动进程

如果我通过Java的ProcessBuilder类启动一个进程,我可以完全访问该进程的标准输入,标准输出和标准错误流,如Java InputStreamsOutputStreams 。 但是,我找不到将这些流无缝连接到System.inSystem.outSystem.err

可以使用redirectErrorStream()来获取包含子进程的标准输出和标准错误的单个InputStream ,然后循环遍历并通过我的标准输出 – 但我找不到一种方法来做到这一点并让用户如果我使用C system()调用,他或她可以输入进程。

这在Java SE 7出现时似乎是可能的 – 我只是想知道现在是否有解决方法。 如果子进程中isatty()的结果通过重定向,则加分。

您需要将Process out,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(); } 

对于System.in使用以下pipein()而不是pipe()

 pipein(System.in, p.getOutputStream()); 

执行:

 private static void pipein(final InputStream src, final OutputStream dest) { new Thread(new Runnable() { public void run() { try { int ret = -1; while ((ret = System.in.read()) != -1) { dest.write(ret); dest.flush(); } } catch (IOException e) { // just exit } } }).start(); }