如何从Process inputStream读取不立即可用

时间:2017-10-18 09:38:51

标签: java fork inputstream

在Java中,如果数据立即可用,则可以预期从过程工作的inputStream中读取数据。 但是当进程不能立即生成数据时,似乎无法检索数据?!

单元测试:

@Test
public void testForkingProcess() throws Exception {
            String [] cmds = new String[]{"echo this is a test", "sleep 2 ; echo this is a test"};
    for(String cmd: cmds) {
        Process p = Runtime.getRuntime().exec(cmd);
        byte[] buf = new byte[100];
        int len = 0;
        long t0 = System.currentTimeMillis();
        while(len < 15 && (System.currentTimeMillis() - t0) < 5000) {
            int newLen = p.getInputStream().read(buf, len, buf.length - len);
            if(newLen != -1) {
                len += newLen;
            }
        }
        long t1 = System.currentTimeMillis();
        System.out.println("elapse time : " + (t1 - t0) +" ms");
        System.out.println("read len : " + len);            
        p.destroy();
    }
}    

控制台输出:

    elapse time : 1 ms
    read len : 15
    elapse time : 5000 ms
    read len : 0

是否有人对此行为以及如何处理流以检索数据有所了解。

另一个简单的例子:

@Test
public void testMoreSimpleForkingProcess() throws Exception {
    String [] cmds = new String[]{"echo this is a test", "sleep 2 ; echo this is a test"};
    for(String cmd: cmds) {
        Process p = Runtime.getRuntime().exec(cmd);
        byte[] buf = new byte[100];
        int len = 0;
        int newLen = 0;
        while(newLen >= 0) {
            newLen = p.getInputStream().read(buf, len, buf.length - len);
            if(newLen != -1) {
                len += newLen;
            }
        }
        p.getInputStream().close();
        System.out.println("read len : " + len);            
        p.destroy();
    }

}

控制台输出:

    read len : 15
    read len : 0

2 个答案:

答案 0 :(得分:2)

  

如何从Process inputStream读取不能立即使用?

块。你不需要计时的东西。您不知道该过程产生输出的速度有多快。只是阻止读取,并重复直到流结束。

您还需要使用错误流,还需要关闭进程的输入流。你也在睡觉时已经收到了流的结尾。没有意义的。

答案 1 :(得分:-1)

好吧实际上问题是在cmd传递给exec Java而不是像shell这样的进程命令。 需要使用ProcessBuilder和bash -i -c