Java 如何从进程inputStream中读取不立即可用的内容

Java 如何从进程inputStream中读取不立即可用的内容,java,fork,inputstream,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: cm

在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();
    }
}    
是否有人知道这种行为以及如何处理流以检索数据

另一个简单的例子:

@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
如何读取无法立即使用的进程inputStream

街区。你不需要计时的东西。你不知道这个过程产生输出的速度有多快。只需在读取中阻塞,并重复,直到流结束


您还需要使用错误流,并且还需要关闭进程的输入流。当已经接收到流结束时,您也在睡觉。毫无意义。

好的,事实上问题是在cmd中传递给execjava,而不是像shell那样处理命令。
需要使用ProcessBuilder和bash-i-c

可以,但如何阻止?直接读取的第一个调用返回流的末尾(-1)块用于什么?您已经到达流的末尾:所以,停止读取,关闭流,您就完成了。好的,谢谢您的回复。事实上,我并不期望exec中出现错误,我认为即使流返回-1,它也可能稍后返回数据。我永远不会忘记阅读错误流现在!!否。如果读取返回-1,则它永远不能“稍后返回数据”。没有更多的数据。那个同龄人已经把烟斗的一端堵住了。而且您必须始终预料到
exec()
中会出现错误,其他任何地方也会出现错误。
    read len : 15
    read len : 0