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
|
public
|
||||||
void close() {
|
void close() {
|
||||||
try {
|
try {
|
||||||
|
if (os != null) {
|
||||||
|
os.flush(); // this goes to the console, so we don't want to close it!
|
||||||
|
}
|
||||||
this.is.close();
|
this.is.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
}
|
}
|
||||||
|
@ -46,33 +49,29 @@ class ProcessProxy extends Thread {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
|
final OutputStream os = this.os;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// this thread will read until there is no more data to read. (this is generally what you want)
|
// 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)
|
// the stream will be closed when the process closes it (usually on exit)
|
||||||
int readInt;
|
int readInt;
|
||||||
|
|
||||||
if (this.os == null) {
|
if (os == null) {
|
||||||
// just read so it won't block.
|
// just read so it won't block.
|
||||||
while ((readInt = this.is.read()) != -1) {
|
while ((readInt = this.is.read()) != -1) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
while ((readInt = this.is.read()) != -1) {
|
while ((readInt = this.is.read()) != -1) {
|
||||||
this.os.write(readInt);
|
os.write(readInt);
|
||||||
// always flush
|
|
||||||
this.os.flush();
|
// flush the output on new line.
|
||||||
|
if (readInt == '\n') {
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ignore) {
|
} catch (Exception 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) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ package dorkbox.util.process;
|
||||||
|
|
||||||
import dorkbox.util.OS;
|
import dorkbox.util.OS;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PrintStream;
|
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:
|
* If you want to save off the output from the process, set a PrintStream to the following:
|
||||||
|
* <pre> {@code
|
||||||
|
*
|
||||||
* ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(8196);
|
* ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(8196);
|
||||||
* PrintStream outputStream = new PrintStream(byteArrayOutputStream);
|
* PrintStream outputStream = new PrintStream(byteArrayOutputStream);
|
||||||
* ...
|
* ...
|
||||||
* String output = byteArrayOutputStream.toString();
|
*
|
||||||
|
* String output = ShellProcessBuilder.getOutput(byteArrayOutputStream);
|
||||||
|
* }</pre>
|
||||||
*/
|
*/
|
||||||
public
|
public
|
||||||
class ShellProcessBuilder {
|
class ShellProcessBuilder {
|
||||||
|
@ -37,6 +42,7 @@ class ShellProcessBuilder {
|
||||||
private final PrintStream outputStream;
|
private final PrintStream outputStream;
|
||||||
private final PrintStream errorStream;
|
private final PrintStream errorStream;
|
||||||
private final InputStream inputStream;
|
private final InputStream inputStream;
|
||||||
|
|
||||||
protected List<String> arguments = new ArrayList<String>();
|
protected List<String> arguments = new ArrayList<String>();
|
||||||
private String workingDirectory = null;
|
private String workingDirectory = null;
|
||||||
private String executableName = null;
|
private String executableName = null;
|
||||||
|
@ -66,9 +72,9 @@ class ShellProcessBuilder {
|
||||||
|
|
||||||
public
|
public
|
||||||
ShellProcessBuilder(InputStream in, PrintStream out, PrintStream err) {
|
ShellProcessBuilder(InputStream in, PrintStream out, PrintStream err) {
|
||||||
|
this.inputStream = in;
|
||||||
this.outputStream = out;
|
this.outputStream = out;
|
||||||
this.errorStream = err;
|
this.errorStream = err;
|
||||||
this.inputStream = in;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -188,16 +194,33 @@ class ShellProcessBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.debugInfo) {
|
if (this.debugInfo) {
|
||||||
this.errorStream.print("Executing: ");
|
if (errorStream != null) {
|
||||||
|
this.errorStream.print("Executing: ");
|
||||||
|
} else {
|
||||||
|
System.err.println("Executing: ");
|
||||||
|
}
|
||||||
Iterator<String> iterator = argumentsList.iterator();
|
Iterator<String> iterator = argumentsList.iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
String s = iterator.next();
|
String s = iterator.next();
|
||||||
this.errorStream.print(s);
|
if (errorStream != null) {
|
||||||
|
this.errorStream.print(s);
|
||||||
|
} else {
|
||||||
|
System.err.print(s);
|
||||||
|
}
|
||||||
if (iterator.hasNext()) {
|
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);
|
ProcessBuilder processBuilder = new ProcessBuilder(argumentsList);
|
||||||
|
@ -213,7 +236,11 @@ class ShellProcessBuilder {
|
||||||
try {
|
try {
|
||||||
this.process = processBuilder.start();
|
this.process = processBuilder.start();
|
||||||
} catch (Exception ex) {
|
} 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);
|
ex.printStackTrace(this.errorStream);
|
||||||
|
|
||||||
if (this.process != null) {
|
if (this.process != null) {
|
||||||
|
@ -221,7 +248,11 @@ class ShellProcessBuilder {
|
||||||
this.process.destroy();
|
this.process.destroy();
|
||||||
this.process = null;
|
this.process = null;
|
||||||
} catch (Exception e) {
|
} 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);
|
e.printStackTrace(this.errorStream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -255,6 +286,7 @@ class ShellProcessBuilder {
|
||||||
readFromProcess_output = new ProcessProxy("Process Reader: " + this.executableName,
|
readFromProcess_output = new ProcessProxy("Process Reader: " + this.executableName,
|
||||||
this.process.getInputStream(),
|
this.process.getInputStream(),
|
||||||
this.outputStream);
|
this.outputStream);
|
||||||
|
|
||||||
if (this.errorStream != this.outputStream) {
|
if (this.errorStream != this.outputStream) {
|
||||||
readFromProcess_error = new ProcessProxy("Process Reader: " + this.executableName,
|
readFromProcess_error = new ProcessProxy("Process Reader: " + this.executableName,
|
||||||
this.process.getErrorStream(),
|
this.process.getErrorStream(),
|
||||||
|
@ -338,4 +370,23 @@ class ShellProcessBuilder {
|
||||||
.removeShutdownHook(hook);
|
.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