Last active
January 30, 2019 14:19
-
-
Save cwilper/6820da1add2fe0b7f8e54e2c2f1ec5bc to your computer and use it in GitHub Desktop.
Java example of using ProcessBuilder synchronously and reading stdout/err from temporary files. See main method.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.atmire.util; | |
import java.io.BufferedReader; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.FileNotFoundException; | |
import java.io.FilterInputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
/** | |
* A simplified interface to invoke OS commands and get their return code, stdout, and stderr contents. | |
* | |
* @see #main(String[]) | |
*/ | |
public class CommandRunner { | |
private final ProcessBuilder builder; | |
private final File outFile; | |
private final File errFile; | |
private InputStream outStream; | |
private InputStream errStream; | |
public CommandRunner(String... command) { | |
try { | |
outFile = File.createTempFile(getClass().getName(), ".out"); | |
errFile = File.createTempFile(getClass().getName(), ".err"); | |
this.builder = new ProcessBuilder() | |
.command(command) | |
.redirectOutput(outFile) | |
.redirectError(errFile); | |
} catch (IOException wontHappen) { | |
throw new RuntimeException(wontHappen); | |
} | |
} | |
public int run() throws IOException, InterruptedException { | |
int exitCode = builder.start().waitFor(); | |
outStream = createTempStream(outFile); | |
errStream = createTempStream(errFile); | |
return exitCode; | |
} | |
public InputStream getStandardOutput() { | |
return outStream; | |
} | |
public InputStream getStandardError() { | |
return errStream; | |
} | |
/** | |
* An {code}InputStream{/code} over a file that deletes it when closed or garbage collected. | |
*/ | |
private InputStream createTempStream(final File tempFile) { | |
if (!tempFile.exists()) { | |
return null; | |
} | |
try { | |
return new FilterInputStream(new FileInputStream(tempFile)) { | |
@Override | |
public void close() { | |
try { | |
in.close(); | |
} catch (IOException ignore) { | |
} | |
deleteTempFile(); | |
} | |
@Override | |
public void finalize() { | |
try { super.finalize(); } catch (Throwable ignore) { } | |
deleteTempFile(); | |
} | |
private void deleteTempFile() { | |
if (tempFile.exists() && !tempFile.delete()) { | |
tempFile.deleteOnExit(); | |
} | |
} | |
}; | |
} catch (FileNotFoundException wontHappen) { | |
throw new RuntimeException(wontHappen); | |
} | |
} | |
/** | |
* Example use of this class. | |
* | |
* @param args os command and args to run | |
* @throws Exception if anything goes wrong | |
*/ | |
public static void main(String[] args) throws Exception { | |
CommandRunner runner = new CommandRunner(args); | |
int exitCode = runner.run(); | |
System.out.println("Exit code: " + exitCode); | |
System.out.println("Standard output:"); | |
printStream(runner.getStandardOutput()); | |
System.out.println("Standard error:"); | |
printStream(runner.getStandardError()); | |
} | |
private static void printStream(InputStream in) throws Exception { | |
if (in == null) return; | |
BufferedReader reader = new BufferedReader(new InputStreamReader(in)); | |
try { | |
String line = reader.readLine(); | |
while (line != null) { | |
System.out.println(line); | |
line = reader.readLine(); | |
} | |
} finally { | |
try { | |
reader.close(); | |
} catch (IOException ignore) { | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment