如果我通过Java ProcessBuilder类启动一个进程,我可以完全访问该进程的标准输入,标准输出和标准错误流,如Java InputStreams
和OutputStreams
。但是,我无法找到将这些流无缝连接到System.in
,System.out
和System.err
的方法。
可以使用redirectErrorStream()
来获取包含子进程的标准输出和标准错误的单个InputStream
,然后循环遍历并通过我的标准输出 - 但我找不到如果我使用C system()
调用,就可以按照他或她的方式让用户输入流程。
这在Java SE 7出现时似乎是可能的 - 我只是想知道现在是否有解决方法。如果子进程中isatty()
的结果通过重定向,则会获得奖励。
答案 0 :(得分:16)
您需要将Process输出,错误和输入流复制到系统版本。最简单的方法是使用Commons IO软件包中的IOUtils类。 copy method看起来就像你需要的那样。复制方法调用需要在单独的线程中。
以下是基本代码:
// 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();
答案 1 :(得分:13)
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();
}
答案 2 :(得分:3)
对于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();
}