在 Java 6 中使用继承的 stdin/stdout/stderr 启动进程
题
如果我通过 Java 启动一个进程 流程构建器 类,我可以像 Java 一样完全访问该进程的标准输入、标准输出和标准错误流 InputStreams
和 OutputStreams
. 。但是,我找不到一种方法将这些流无缝连接到 System.in
, System.out
, , 和 System.err
.
可以使用 redirectErrorStream()
得到一个 InputStream
包含子进程的标准输出和标准错误,只需循环它并通过我的标准输出发送它 - 但我找不到一种方法来做到这一点并让用户输入到进程中,就像他或她可以的那样,如果我使用了C system()
称呼。
当 Java SE 7 发布时,这似乎是可能的——我只是想知道现在是否有解决方法。如果结果如下,则奖励积分 isatty()
在子进程中进行重定向。
解决方案
您需要复制 过程 out、err 和系统版本的输入流。最简单的方法是使用 IOUtils 来自 Commons IO 包的类。这 复制法 看起来就是你需要的。复制方法调用需要位于单独的线程中。
这是基本代码:
// 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();
}
不隶属于 StackOverflow