使用Futuretask的带有inputstream读取器的Java异步进程运行程序

使用Futuretask的带有inputstream读取器的Java异步进程运行程序,java,asynchronous,process,futuretask,Java,Asynchronous,Process,Futuretask,我试图运行一个异步进程并获取它的inputstream(如果有) 这是我的代码: CommandCall commandCall = new CommandCall(commands); ExecutorService executor = Executors.newSingleThreadExecutor(); Future<Integer> task = executor.submit(commandCall); 观察进程输出的行为本身应该在自己的线程中

我试图运行一个异步进程并获取它的inputstream(如果有)

这是我的代码:

    CommandCall commandCall = new CommandCall(commands);
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<Integer> task = executor.submit(commandCall);

观察进程输出的行为本身应该在自己的线程中。一旦进程终止,这个线程也应该终止

所以基本上你可以这样做:

@Override
public Integer call() throws Exception {
    Thread outputObserver = null;

    try(ByteArrayOutputStream  baos = new ByteArrayOutputStream()) {
        this.process = new ProcessBuilder(commands).start();
        outputObserver = new OutputObserver(process.getInputStream(), baos);
        outputObserver.start();
        this.retval = process.waitFor();
        this.output = baos.toByteArray();
    }finally{
        if(outputObserver != null) outputObserver.interrupt();
    }

    return this.retval;
}

private static OutputObserver extends Thread {
    private final InputStream input;
    private final OutputStream output;

    OutputObserver(InputStream input, OutputStream output) {
        this.input = input;
        this.output = output;
    }

    @Override
    public void run() {
         while(!Thread.interrupted()) {
             // Copy bytes from input to output here (handling any exceptions).
             // Maybe use 3rd party libs for that.
         }
         // Make sure to copy remaining bytes here, too.
    }
}
几点注意:

  • 我没有测试任何代码。也许我犯了一些微妙的错误,但方向应该是明确的
  • 通常我不会扩展
    线程
    ,而是实现
    可运行
    。我只是不想把事情复杂化
  • 我没有提供将字节从输入流复制到输出流的代码。如果你需要这方面的帮助,可以在网上搜索一下。你会找到很多解决办法
@Override
public Integer call() throws Exception {
    InputStream is=null;
    try{
        process = new ProcessBuilder(commands).start();
        is=process.getInputStream();
        int len;
        int size = 1024;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        byte[] buf = new byte[size];
        while ((len = is.read(buf, 0, size)) != -1)
            bos.write(buf, 0, len);
        output = bos.toByteArray();
        retval= process.waitFor();
    }finally{
        try{
            if(is!=null) is.close();
        }catch(Exception e){}
    }
    return retval;
}
@Override
public Integer call() throws Exception {
    Thread outputObserver = null;

    try(ByteArrayOutputStream  baos = new ByteArrayOutputStream()) {
        this.process = new ProcessBuilder(commands).start();
        outputObserver = new OutputObserver(process.getInputStream(), baos);
        outputObserver.start();
        this.retval = process.waitFor();
        this.output = baos.toByteArray();
    }finally{
        if(outputObserver != null) outputObserver.interrupt();
    }

    return this.retval;
}

private static OutputObserver extends Thread {
    private final InputStream input;
    private final OutputStream output;

    OutputObserver(InputStream input, OutputStream output) {
        this.input = input;
        this.output = output;
    }

    @Override
    public void run() {
         while(!Thread.interrupted()) {
             // Copy bytes from input to output here (handling any exceptions).
             // Maybe use 3rd party libs for that.
         }
         // Make sure to copy remaining bytes here, too.
    }
}