Skip to content

Instantly share code, notes, and snippets.

@cwilper
Last active January 30, 2019 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cwilper/6820da1add2fe0b7f8e54e2c2f1ec5bc to your computer and use it in GitHub Desktop.
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.
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