0

In the code below, the author uses Runtime to call a sub-process. But I don't understand why he uses StreamGobbler. What will happen if replace it by InputStream? Please help me, thanks!

public class GoodWindowsExec   
{   
    public static void main(String args[])   
    {   

        try   
        {               
            String osName = System.getProperty("os.name" );   
            System.out.println("osName: " + osName);   
            String[] cmd = new String[3];   

            if(osName.equals("Windows XP") ||osName.equals("Windows 2000"))   
            {   
                cmd[0] = "cmd.exe" ;   
                cmd[1] = "/C" ;   
                cmd[2] = args[0];   
            }   
            else if( osName.equals( "Windows 98" ) )   
            {   
                cmd[0] = "command.com" ;   
                cmd[1] = "/C" ;   
                cmd[2] = args[0];   
            }   

            Runtime rt = Runtime.getRuntime();   
            System.out.println("Execing " + cmd[0] + " " + cmd[1]+ " " + cmd[2]);   
            Process proc = rt.exec(cmd);   
            // any error message?   
            StreamGobbler errorGobbler = new StreamGobbler(proc.getErrorStream(), "ERROR");  //Can I replace StreamGobbler by InputStream?        
            // any output?   
            StreamGobbler outputGobbler = new StreamGobbler(proc.getInputStream(), "OUTPUT");   //As above

            // kick them off   
            errorGobbler.start();   
            outputGobbler.start();   

            // any error???   
            int exitVal = proc.waitFor();   
            System.out.println("ExitValue: " + exitVal);   

        } catch (Throwable t){   
            t.printStackTrace();   
        }   
    }   
}

BufferedReader brNormal = new BufferedReader(new InputStreamReader(process.getInputStream()));
String s = null;
while ((s = brNormal.readLine()) != null) {
    logger.info("RawToRgbConverter.exe", s);
}
brNormal.close();
BufferedReader brError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while ((s = brError.readLine()) != null) {
    logger.error("RawToRgbConverter.exe", s);
}
brError.close();
Mansuro
  • 4,558
  • 4
  • 36
  • 76
Niubility
  • 577
  • 5
  • 19
  • What 3rd party library does `StreamGobbler` come from? From the code it appears that it contains a thread that reads the stream, probably to an in-memory buffer. An `InputStream` would not do the same thing. – Jim Garrison Aug 09 '16 at 05:54
  • I add my own code in the question, in which I use InputStream. I haven't found anything wrong in it. Appreciate your correcting. – Niubility Aug 09 '16 at 07:10

1 Answers1

1

Even as I don't know the StreamGobbler class, this is obviously a threaded implementation to copy the output and error streams to a given target. Thus, no you cannot simply replace it, as the multi-threading is indeed necessary. A simple input stream would just sit there, but not actually do anything.

Note however, that this complete solution is outdated since Java 1.5 which introduced the ProcessBuilder and the automatic redirects. See the javadoc at https://docs.oracle.com/javase/8/docs/api/

mtj
  • 3,381
  • 19
  • 30
  • Thanks for your reply. I add my own code in the question above, in which I use InputStream. I haven't found anything wrong in it. Appreciate your correcting. – Niubility Aug 09 '16 at 07:15
  • You actually need to start different threads as the reading of the streams may block one another. Have a look at the accepted answer here http://stackoverflow.com/questions/33418502/java-process-with-concurrent-input-output-streams for a threaded example. – mtj Aug 09 '16 at 09:09