Java 如何将流程的输入/输出流复制到其系统对应方?
这是一个后续行动。答案表明有 将进程输出、错误和输入流复制到系统版本 使用Java 如何将流程的输入/输出流复制到其系统对应方?,java,process,io,stream,pipe,Java,Process,Io,Stream,Pipe,这是一个后续行动。答案表明有 将进程输出、错误和输入流复制到系统版本 使用IOUtils.copy如下(修复各种编译错误后): 但是,生成的代码不适用于交互式进程,例如执行sh-i命令的进程。在后一种情况下,对任何sh命令都没有响应 因此,我的问题是:您能推荐一种替代方法来复制将与交互进程一起工作的流吗?问题是,IOUtil.copy()正在运行,而InputStream中有数据要复制。由于您的进程只会不时生成数据,IOUtil.copy()会退出,因为它认为没有要复制的数据 只需手动复制数据并
IOUtils.copy
如下(修复各种编译错误后):
但是,生成的代码不适用于交互式进程,例如执行sh-i
命令的进程。在后一种情况下,对任何sh
命令都没有响应
因此,我的问题是:您能推荐一种替代方法来复制将与交互进程一起工作的流吗?问题是,
IOUtil.copy()
正在运行,而InputStream中有数据要复制。由于您的进程只会不时生成数据,IOUtil.copy()
会退出,因为它认为没有要复制的数据
只需手动复制数据并使用布尔值将线程形式停止在外部:
byte[] buf = new byte[1024];
int len;
while (threadRunning) { // threadRunning is a boolean set outside of your thread
if((len = input.read(buf)) > 0){
output.write(buf, 0, len);
}
}
这将读取inputStream上可用的字节数,并将所有字节复制到输出。内部InputStream将线程放入sowait()
,然后在数据可用时将其唤醒。因此,在这种情况下,它尽可能地高效。
进程。getOutputStream()
返回一个BufferedOutputStream
,因此如果您想让输入真正到达子进程,您必须在每次写入()之后调用flush()
您还可以重写示例,在一个线程上执行所有操作(尽管它使用轮询同时读取System.in和进程的stdout):
您应该改用ProcessBuilder.redirectOutput
方法&friends。阅读更多内容感谢您的建议。但是,IOUtil.copy()
在到达流的末尾之前不会退出,因此它与您的代码没有太大区别,因为您的代码与sh
有相同的问题。请看一下
byte[] buf = new byte[1024];
int len;
while (threadRunning) { // threadRunning is a boolean set outside of your thread
if((len = input.read(buf)) > 0){
output.write(buf, 0, len);
}
}
import java.io.*;
public class TestProcessIO {
public static boolean isAlive(Process p) {
try {
p.exitValue();
return false;
}
catch (IllegalThreadStateException e) {
return true;
}
}
public static void main(String[] args) throws IOException {
ProcessBuilder builder = new ProcessBuilder("bash", "-i");
builder.redirectErrorStream(true); // so we can ignore the error stream
Process process = builder.start();
InputStream out = process.getInputStream();
OutputStream in = process.getOutputStream();
byte[] buffer = new byte[4000];
while (isAlive(process)) {
int no = out.available();
if (no > 0) {
int n = out.read(buffer, 0, Math.min(no, buffer.length));
System.out.println(new String(buffer, 0, n));
}
int ni = System.in.available();
if (ni > 0) {
int n = System.in.read(buffer, 0, Math.min(ni, buffer.length));
in.write(buffer, 0, n);
in.flush();
}
try {
Thread.sleep(10);
}
catch (InterruptedException e) {
}
}
System.out.println(process.exitValue());
}
}