2017-10-18 102 views
0

在从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

如何从流程的inputStream没有立即阅读?

Block。你不需要计时的东西。你不知道该过程将产生多大的输出。只需读取,并重复,直到流结束。

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

+0

确定但是如何阻止?首先调用读取直接返回流结束(-1) –

+0

块为什么?您已达到流的末端:因此,请停止阅读,关闭流,您就完成了。 – EJP

+0

好的谢谢你的回复,实际上我并不期待exec的错误,我认为即使流返回-1它可能会在稍后返回数据。 我永远不会忘记现在阅读错误流! –

-1

其实问题是在cmd中传递给exec Java不像shell那样处理命令。 需要使用ProcessBuilder和bash -i -c

相关问题