Streaming output with commons-exec?

2019-06-25 00:18发布

问题:

Can anyone give me an example of how to stream the output of an external program executed with DefaultExecutor? I'm not finding any documentation describing how to do this.

My external process will run for several hours, so just grabbing all output data isn't feasible; it must be streamed.

回答1:

Note: this solution is synchronous, so it won't stream. You'll need to read is in a separate thread, or use the asynchronous version of the execute command.

private InputStream getStream() {

 String dataParsingCommand = "java";

PipedOutputStream output = new PipedOutputStream();
PumpStreamHandler psh = new PumpStreamHandler(output);

CommandLine cl = CommandLine.parse(command);
cl.addArgument("-jar");
cl.addArgument(dataParserPath);

DefaultExecutor exec = new DefaultExecutor();
DataInputStream is = null;
try {
    is = new DataInputStream(new PipedInputStream(output));
    exec.setStreamHandler(psh);
    exec.execute(dataParserCommandLine);
} catch (ExecuteException ex) {
} catch (IOException ex) {
}

return is;
}


回答2:

Below is some sample code for using Runtime.exec. it would be simple to adapt it to your use. From http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=4

import java.util.*;
import java.io.*;
class StreamGobbler extends Thread
{
    InputStream is;
    String type;

    StreamGobbler(InputStream is, String type)
    {
        this.is = is;
        this.type = type;
    }

    public void run()
    {
        try
        {
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line=null;
            while ( (line = br.readLine()) != null)
                System.out.println(type + ">" + line);    
            } catch (IOException ioe)
              {
                ioe.printStackTrace();  
              }
    }
}


public class GoodWindowsExec
{
    public static void main(String args[])
    {
        if (args.length < 1)
        {
            System.out.println("USAGE: java GoodWindowsExec <cmd>");
            System.exit(1);
        }

        try
        {            
            String osName = System.getProperty("os.name" );
            String[] cmd = new String[3];
            if( osName.equals( "Windows NT" ) )
            {
                cmd[0] = "cmd.exe" ;
                cmd[1] = "/C" ;
                cmd[2] = args[0];
            }
            else if( osName.equals( "Windows 95" ) )
            {
                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");            

            // any output?
            StreamGobbler outputGobbler = new 
                StreamGobbler(proc.getInputStream(), "OUTPUT");

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

            // any error???
            int exitVal = proc.waitFor();
            System.out.println("ExitValue: " + exitVal);        
        } catch (Throwable t)
          {
            t.printStackTrace();
          }
    }
}  

EDIT: This does not exactly answer the question, since it uses the JDK classes, but it works.