运行子流程,使用Java正确地为其提供输入和输出

运行子流程,使用Java正确地为其提供输入和输出,第1张

运行子流程,使用Java正确地为其提供输入输出

你需要复制子流之间的输入和输出

System
流(
System.in
System.out
System.err
)。这与我最近的疑问有关。到目前为止,我发现的最佳解决方案是:

import java.io.FileInputStream;import java.io.FilterInputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.lang.reflect.Field;import java.nio.ByteBuffer;import java.nio.channels.AsynchronousCloseException;import java.nio.channels.FileChannel;class StreamCopier implements Runnable {    private InputStream in;    private OutputStream out;    public StreamCopier(InputStream in, OutputStream out) {        this.in = in;        this.out = out;    }    public void run() {        try { int n; byte[] buffer = new byte[4096]; while ((n = in.read(buffer)) != -1) {     out.write(buffer, 0, n);     out.flush(); }        }        catch (IOException e) { System.out.println(e);        }    }}class InputCopier implements Runnable {    private FileChannel in;    private OutputStream out;    public InputCopier(FileChannel in, OutputStream out) {        this.in = in;        this.out = out;    }    public void run() {        try { int n; ByteBuffer buffer = ByteBuffer.allocate(4096); while ((n = in.read(buffer)) != -1) {     out.write(buffer.array(), 0, n);     out.flush(); } out.close();        }        catch (AsynchronousCloseException e) {}        catch (IOException e) { System.out.println(e);        }    }}public class Test {    private static FileChannel getChannel(InputStream in) throws NoSuchFieldException, IllegalAccessException {        Field f = FilterInputStream.class.getDeclaredField("in");        f.setAccessible(true);        while (in instanceof FilterInputStream) in = (InputStream)f.get((FilterInputStream)in);        return ((FileInputStream)in).getChannel();    }    public static void main(String[] args) throws IOException, InterruptedException,        NoSuchFieldException, IllegalAccessException {        Process process = Runtime.getRuntime().exec("sh -i +m");        Thread outThread = new Thread(new StreamCopier(     process.getInputStream(), System.out));        outThread.start();        Thread errThread = new Thread(new StreamCopier(     process.getErrorStream(), System.err));        errThread.start();        Thread inThread = new Thread(new InputCopier(     getChannel(System.in), process.getOutputStream()));        inThread.start();        process.waitFor();        System.in.close();        outThread.join();        errThread.join();        inThread.join();    }}

这里最棘手的部分是从中提取频道

System.in
。否则,子进程终止时,您将无法中断读取输入的线程

这种方法有一个严重的缺点:关闭后,

System.in
您将无法再读取它。我当前正在使用的解决方法是为所有子流程使用一个输入重定向线程。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5488269.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-12
下一篇2022-12-12

发表评论

登录后才能评论

评论列表(0条)

    保存