I'm building a process in Java using ProcessBuilder as follows:
ProcessBuilder pb = new ProcessBuilder() .command("somecommand", "arg1", "arg2") .redirectErrorStream(true); Process p = pb.start(); InputStream stdOut = p.getInputStream();
Now my problem is the following: I would like to capture whatever is going through stdout and/or stderr of that process and redirect it to System.out
asynchronously. I want the process and its output redirection to run in the background. So far, the only way I've found to do this is to manually spawn a new thread that will continuously read from stdOut
and then call the appropriate write()
method of System.out
.
new Thread(new Runnable(){ public void run(){ byte[] buffer = new byte[8192]; int len = -1; while((len = stdOut.read(buffer)) > 0){ System.out.write(buffer, 0, len); } } }).start();
While that approach kind of works, it feels a bit dirty. And on top of that, it gives me one more thread to manage and terminate correctly. Is there any better way to do this?
Use ProcessBuilder.inheritIO
, it sets the source and destination for subprocess standard I/O to be the same as those of the current Java process.
Process p = new ProcessBuilder().inheritIO().command("command1").start();
If Java 7 is not an option
public static void main(String[] args) throws Exception { Process p = Runtime.getRuntime().exec("cmd /c dir"); inheritIO(p.getInputStream(), System.out); inheritIO(p.getErrorStream(), System.err); } private static void inheritIO(final InputStream src, final PrintStream dest) { new Thread(new Runnable() { public void run() { Scanner sc = new Scanner(src); while (sc.hasNextLine()) { dest.println(sc.nextLine()); } } }).start(); }
Threads will die automatically when subprocess finishes, because src
will EOF.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With