How to copy input/output streams of the Process to their System counterparts?

前端 未结 3 2114
说谎
说谎 2020-12-09 13:32

This is a follow up to this question. The answer suggested there is

to copy the Process out, err, and input streams to the System versions

3条回答
  •  一整个雨季
    2020-12-09 14:09

    Process.getOutputStream() returns a BufferedOutputStream, so if you want your input to actually get to the subprocess you have to call flush() after every write().

    You can also rewrite your example to do everything on one thread (although it uses polling to read both System.in and the process' stdout at the same time):

    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());
      }
    }
    

提交回复
热议问题