Delay when reading output from process from Runtime.getRuntime().exec()
I want to read the stdout from a process that I am starting with exec(). My code does:
p = Runtime.getRuntime().exec(command, null, dir);
stdOut =new BufferedReader(new InputStreamReader(p.getInputStream()));
while (stop_called ==false){
if (stdOut !=null){
int readBytes = 0;
try{
if (stdOut.ready()){
readBytes = stdOut.read(charArray, 0, BYTE_ARRAY_SIZE);
}
}
catch (IOException e){
readBytes = 0;
}
if (listener !=null){
if (readBytes > 0){
listener.newStdoutData(new String(charArray, 0, readBytes));
}
}
}
My problem is that my listener.newStdoutData is called only when a bunch of data has been produced. So if my process in generating 1 line of text per second, then the data are read only after about 30 seconds. What do I have to do to receive one text line at the time? Is there a layer of buffer somewhere that I have to disable?
# 1
Because what happens when in.ready() is false?
You spin in a loop, hogging the CPU and taking it away from the process whose output you are waiting for, and slowing everything down generally.
Get rid of it, and just block in the read.
See also the discussion of InputStream.available() in http://forum.java.sun.com/thread.jspa?threadID=5186815&tstart=0, which also applies to Reader.ready().
ejpa at 2007-7-12 20:18:04 >

# 2
Hi,
I didn't include all my code in my previous message but I was sleeping at the end of each while interation using:
try {
Thread.sleep(100);
}
catch (InterruptedException e) {
}
In the same while loop I am also reading STDERR and writing to STDIN of the process so it wouldn't be a good idea to block on the read because this will also block my other operations. And also I don't want to use many different threads to manage the inputs/outputs of a single process.
What do you think?
# 3
> And also I don't want to
> use many different threads to manage the
> inputs/outputs of a single process.
>
> What do you think?
I think you are wrong. I always use at least two treads when using Runtime.exec(). I usually use the thread that invokes the Runtime.exec() to process stdout and a separate thread to process stderr. If I need to send data to stdin I usually use the Runtime.exec() thread for that and process stdout in a separate thread.
But of course I think you are free to do it any way you want even if it is wrong.