Standard version of reading Java from an external program using an input stream

I am trying to develop a class that reads the standard output of an external program (using an instance of Process, Runtime.getRuntime (). Exec (cmdLine, env, dir)). The program accepts user inputs during the process and will not work until a valid input is specified; this seems to cause the problem in the way I try to read its output:

egm.execute(); // run external the program with specified arguments BufferedInputStream stdout = new BufferedInputStream(egm.getInputStream()); BufferedInputStream stderr = new BufferedInputStream(egm.getErrorStream()); BufferedOutputStream stdin = new BufferedOutputStream(egm.getOutputStream()); int c; //standard output input stream int e; //standadr error input stream while((c=stdout.read()) != -1) //<-- the Java class stops here, waiting for input? { egm.processStdOutStream((char)c); } while((e=stderr.read()) != -1) { egm.processStdErrStream((char)e); } //... 

How can I fix this so that the program accepts a valid input and continues? Any help in solving this problem would be great!

+4
source share
5 answers

You must use both stdout programs and stderr at the same time to avoid script blocking.

For more details see this article and, in particular, pay attention to the StreamGobbler mechanism, which captures stdout / err in separate streams. This is necessary to prevent blocking and is the source of numerous errors if you do not do it right!

+7
source

In this situation, you should have separate streams reading InputStream and ErrStream.

You can also do something like:

 public void run() { while( iShouldStillBeRunning ) { int c; while( stdout.available() > 0 && ((c=stdout.read()) != -1)) { egm.processStdOutStream((char)c); } Thread.sleep(100); } } 

Because you will be locked on stdout.read() until the input appears.

+2
source

On the one hand, this can block if it is written to the error stream and has run out of buffer - you do not read from the error stream until the output stream completes completely.

Then you say that user input is required during the process - do you give it any user input by writing to stdin ? If it is waiting for input, you should write it to stdin accordingly and reset it.

+1
source

You do not say in your question what actually happens when you try to run this. Please update the detailed description of what will happen and what you expect instead. Bonus points for telling us what kind of team it is.

Also, is it UNIX / Linux or Windows? If it is UNIX / Linux (or some other POSIX platform), the program may look for input on / dev / console instead of / dev / stdin for security reasons.

0
source

In the interest of others who are looking for solutions to this problem, I just want to add that I had a very similar problem. But in my case, the program also expected one line input. Therefore, for asynchronous control of all three channels, three threads must be enabled.

Without writing to the output (i.e., the stdin of the executing program), it was not possible to completely capture the input (i.e., output from the executing program). Recording on it hung the process.

The decision was three words by John Skeet: "and rinse it." After adding the flash do not hang. Thanks!

0
source

All Articles