Cleaned up process std i/o. Changed where/how flushing runs when finished. Added better docs. Added getOutput() to safely convert baos to string

This commit is contained in:
nathan 2015-10-27 01:44:49 +01:00
parent 9214880c98
commit 9be830786c
2 changed files with 72 additions and 22 deletions

View File

@ -38,6 +38,9 @@ class ProcessProxy extends Thread {
public
void close() {
try {
if (os != null) {
os.flush(); // this goes to the console, so we don't want to close it!
}
this.is.close();
} catch (IOException e) {
}
@ -46,33 +49,29 @@ class ProcessProxy extends Thread {
@Override
public
void run() {
final OutputStream os = this.os;
try {
// this thread will read until there is no more data to read. (this is generally what you want)
// the stream will be closed when the process closes it (usually on exit)
int readInt;
if (this.os == null) {
if (os == null) {
// just read so it won't block.
while ((readInt = this.is.read()) != -1) {
}
}
else {
while ((readInt = this.is.read()) != -1) {
this.os.write(readInt);
// always flush
this.os.flush();
os.write(readInt);
// flush the output on new line.
if (readInt == '\n') {
os.flush();
}
}
}
} catch (IOException ignore) {
} catch (IllegalArgumentException e) {
} finally {
try {
if (this.os != null) {
this.os.flush(); // this goes to the console, so we don't want to close it!
}
this.is.close();
} catch (IOException ignore) {
}
} catch (Exception ignore) {
}
}
}

View File

@ -17,6 +17,7 @@ package dorkbox.util.process;
import dorkbox.util.OS;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.PrintStream;
@ -26,10 +27,14 @@ import java.util.List;
/**
* If you want to save off the output from the process, set a PrintStream to the following:
* <pre> {@code
*
* ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(8196);
* PrintStream outputStream = new PrintStream(byteArrayOutputStream);
* ...
* String output = byteArrayOutputStream.toString();
*
* String output = ShellProcessBuilder.getOutput(byteArrayOutputStream);
* }</pre>
*/
public
class ShellProcessBuilder {
@ -37,6 +42,7 @@ class ShellProcessBuilder {
private final PrintStream outputStream;
private final PrintStream errorStream;
private final InputStream inputStream;
protected List<String> arguments = new ArrayList<String>();
private String workingDirectory = null;
private String executableName = null;
@ -66,9 +72,9 @@ class ShellProcessBuilder {
public
ShellProcessBuilder(InputStream in, PrintStream out, PrintStream err) {
this.inputStream = in;
this.outputStream = out;
this.errorStream = err;
this.inputStream = in;
}
/**
@ -188,16 +194,33 @@ class ShellProcessBuilder {
}
if (this.debugInfo) {
this.errorStream.print("Executing: ");
if (errorStream != null) {
this.errorStream.print("Executing: ");
} else {
System.err.println("Executing: ");
}
Iterator<String> iterator = argumentsList.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
this.errorStream.print(s);
if (errorStream != null) {
this.errorStream.print(s);
} else {
System.err.print(s);
}
if (iterator.hasNext()) {
this.errorStream.print(" ");
if (errorStream != null) {
this.errorStream.print(" ");
} else {
System.err.print(" ");
}
}
}
this.errorStream.print(OS.LINE_SEPARATOR);
if (errorStream != null) {
this.errorStream.print(OS.LINE_SEPARATOR);
} else {
System.err.print(OS.LINE_SEPARATOR);
}
}
ProcessBuilder processBuilder = new ProcessBuilder(argumentsList);
@ -213,7 +236,11 @@ class ShellProcessBuilder {
try {
this.process = processBuilder.start();
} catch (Exception ex) {
this.errorStream.println("There was a problem executing the program. Details:\n");
if (errorStream != null) {
this.errorStream.println("There was a problem executing the program. Details:");
} else {
System.err.println("There was a problem executing the program. Details:");
}
ex.printStackTrace(this.errorStream);
if (this.process != null) {
@ -221,7 +248,11 @@ class ShellProcessBuilder {
this.process.destroy();
this.process = null;
} catch (Exception e) {
this.errorStream.println("Error destroying process: \n");
if (errorStream != null) {
this.errorStream.println("Error destroying process:");
} else {
System.err.println("Error destroying process:");
}
e.printStackTrace(this.errorStream);
}
}
@ -255,6 +286,7 @@ class ShellProcessBuilder {
readFromProcess_output = new ProcessProxy("Process Reader: " + this.executableName,
this.process.getInputStream(),
this.outputStream);
if (this.errorStream != this.outputStream) {
readFromProcess_error = new ProcessProxy("Process Reader: " + this.executableName,
this.process.getErrorStream(),
@ -338,4 +370,23 @@ class ShellProcessBuilder {
.removeShutdownHook(hook);
}
}
/**
* Converts the baos to a string in a safe way. There might be a trailing newline character at the end of this output.
*
* @param byteArrayOutputStream the baos that is used in the {@link ShellProcessBuilder#ShellProcessBuilder(PrintStream)} (or similar
* calls)
*
* @return A string representing the output of the process
*/
public static
String getOutput(final ByteArrayOutputStream byteArrayOutputStream) {
String s;
synchronized (byteArrayOutputStream) {
s = byteArrayOutputStream.toString();
byteArrayOutputStream.reset();
}
return s;
}
}