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:
parent
9214880c98
commit
9be830786c
|
@ -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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user