在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
答案 0 :(得分:2)
如何从Process inputStream读取不能立即使用?
块。你不需要计时的东西。您不知道该过程产生输出的速度有多快。只是阻止读取,并重复直到流结束。
您还需要使用错误流,还需要关闭进程的输入流。你也在睡觉时已经收到了流的结尾。没有意义的。
答案 1 :(得分:-1)
好吧实际上问题是在cmd传递给exec Java而不是像shell这样的进程命令。 需要使用ProcessBuilder和bash -i -c