Why is the InputStreamReader not reading the output of the process in real time?
I am trying to use ProcessBuilder
to run some external commands like ifstat
or vmstat
in Linux.
Such commands support custom sampling intervals. If I add a sampling interval to an external command, for example ifstat 20
, then the command is output like this:
coolcfan@coolcfan-PC:~$ ifstat 20
eth0 wlan0 vmnet1 vmnet8
KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out
after 20 seconds
41.29 1.06 0.36 0.00 0.00 0.00 0.00 0.00
after 20 seconds
16.67 0.58 0.38 0.00 0.00 0.00 0.00 0.00
However , when I run the command using Java code, the first part of the output will be read after 20 seconds, for example:
Start running "ifstat 20"
after 20 seconds
eth0 wlan0 vmnet1 vmnet8
KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out KB/s in KB/s out
66.61 1.73 1.29 0.01 0.00 0.00 0.00 0.00
When I use NIO server to run the command and use SocketChannel to send the output to the client, the problem is even more serious ... (my client needs to wait another 20 seconds to get the server output after the server shows the first output which is 20 seconds after starting process)
And I noticed that the output delay length is related to the I interval set in the command.
So why is the ISR not reading the live output?
Simple code snippet to demonstrate my question:
public static void main(String[] args) {
ProcessBuilder pb = new ProcessBuilder();
pb.command("ifstat 20".trim().split(" "));
Process p = null;
System.out.println("Start running \"ifstat 20\"");
try {
p = pb.start();
char[] buf = new char[512];
InputStreamReader isr = new InputStreamReader(p.getInputStream());
int count = -1;
while ((count = isr.read(buf, 0, buf.length)) != -1) {
System.out.print(new String(buf, 0, count));
}
}
catch (IOException ioe) {
}
}
Update:
As Peter points out, this is not a Java related issue. This is a pipeline delay .
But I still donβt understand why it vmstat 20 | cat
doesnβt have this delay, but ifstat 20 | cat
will delay to show the heads?
source to share