In my program I have a SwingWorker
starting a background process. The background process's error stream is redirected to stdout
, and the stdout
stream is written out (line by line) to a JTextArea
. I thought I was consuming the stdout
stream with this
BufferedReader processOut = new BufferedReader(
new InputStreamReader(p.getInputStream()));
And with this inside the SwingWorker's doInBackground:
String line;
while((line = processOut.readLine()) != null)
process(line);
On my machine, the process executes to completion and the Text Area is periodically updated. The process freezes in the background on other computers though. I've increased the size of the default command
window, so that might be why I can't get any process to freeze on my computer (that is probably very wrong from the more that I read).
I tried redirecting the output inside the ProcessBuilder
command with > log.txt
(I'm on Windows 7 currently) but I think that's causing the p.getInputStream()
call to crash.
How can I either consume the stdout of the subprocess properly inside my SwingWorker
class, or is it possible to pipe the output to a file and still get the output to print
to the JTextArea
.
Edit:
I read here That an input stream needs to be read promptly to be consumed. I've provided the loop that processes the input stream below. I would assume that the pipe doesn't get more than 4K of data before it is read, but I can't assume anything at this point.
while(processIsAlive())
{
if(isCancelled())
{
try
{
p.destroy();
p.waitFor();
return 1;
}
catch(Exception e){}
}
try
{
//Update Text Area
//get output from process
while((line = processOut.readLine()) != null)
{
//print output to text area
publish(line);
}
sleep(1000);
}
catch(Exception e){}
}
EDIT 2:
I thought that having the process redirected to a file, then putting an InputStream
on that same file would be impossible, but its not crashing my program and the GUI is still updated properly. I'm going to go test this on the problematic machine, then I'm going to mark it as an answer if it works.
All I did was redirect the process to a file:
pb.redirectOutput(new File("log.txt"));
And put the InputStream
on that file instead of the process stdout
stream.
processOut = new BufferedReader(new FileReader("log.txt"));