Hallo Leute,
habe leider ein Problem, dass ich noch nicht lösen konnte und an dem ich fast am verzweifeln bin ???:L .
Ich versuche an einen Process mehrere Befehle zu senden. Das klappt bei mir aber nicht so ganz wie es soll.
Eine Instanz Process p wird in der Klasse ConsoleProcess gestartet (Singleton-Muster). In der selben Klasse kann ich über eine Methode execProc individuelle Befehle - die nacheinander in dem Process ausgeführt werden sollen - senden.
Das ist die Idee, die dahinter steht. Allerdings funktioniert das nur für den ersten Befehl den ich sende. Führe ich einen weiteren Befehl aus, wird eine Exception geschmissen.
Allerdings weiß ich nicht warum???? (Meine Idee ist, dass der Process beendet wird bevor überhaupt der nachfolgende Befehl ausgeführt wird.)
Hoffentlich könnt ihr mir weiterhelfen - weiß leider nicht mehr weiter.
Anbei der komplette lauffähige Code. Bin wirklich dankbar für jede Hilfe.
Der Code:
EDIT: Out- und Inputstreams werden nun nicht mehr geschlossen. + Thread-sichere Methode für execProc()
Klasse ProcessesMain
Klasse ConsoleProcess
Klasse StreamChoker
Klasse StreamGobbler
habe leider ein Problem, dass ich noch nicht lösen konnte und an dem ich fast am verzweifeln bin ???:L .
Ich versuche an einen Process mehrere Befehle zu senden. Das klappt bei mir aber nicht so ganz wie es soll.
Eine Instanz Process p wird in der Klasse ConsoleProcess gestartet (Singleton-Muster). In der selben Klasse kann ich über eine Methode execProc individuelle Befehle - die nacheinander in dem Process ausgeführt werden sollen - senden.
Das ist die Idee, die dahinter steht. Allerdings funktioniert das nur für den ersten Befehl den ich sende. Führe ich einen weiteren Befehl aus, wird eine Exception geschmissen.
Allerdings weiß ich nicht warum???? (Meine Idee ist, dass der Process beendet wird bevor überhaupt der nachfolgende Befehl ausgeführt wird.)
Hoffentlich könnt ihr mir weiterhelfen - weiß leider nicht mehr weiter.
Anbei der komplette lauffähige Code. Bin wirklich dankbar für jede Hilfe.
Der Code:
EDIT: Out- und Inputstreams werden nun nicht mehr geschlossen. + Thread-sichere Methode für execProc()
Klasse ProcessesMain
Code:
import java.io.IOException;
public class ProcessesMain {
public static void main(String[] args) throws IOException {
// Get instance of process.
ConsoleProcess cp = ConsoleProcess.getInstance();
cp.execProc("include x.grs");
cp.execProc("show graph ycomp");
cp.execProc("debug enable");
cp.execProc("debug disable");
}
}
Klasse ConsoleProcess
Code:
import java.io.IOException;
/** This class handles one started process. */
public class ConsoleProcess {
/** A process to run the GrShell in a command prompt (DOS console). */
private Process p;
/** The single instance of ConsoleProcess. */
private static ConsoleProcess cp;
private ConsoleProcess() { // A private constructor - a singleton pattern
initProc();
}
/* Returns instance of process console. */
public static ConsoleProcess getInstance() {
if (cp == null) {
cp = new ConsoleProcess();
}
return cp;
}
/* Create the process builder to start the process. */
private void initProc() {
if (p == null) {
// Start a command process. Currently only Windows based
// operating systems are supported.
ProcessBuilder pb = new ProcessBuilder("grshell");
try {
p = pb.start();
} catch (IOException e) {
System.err
.println("ERR: ProcessBuilder did not start the process.");
System.err.println(e.getMessage());
}
}
}
/* Sends and executes a command. Will be executed within threads (StreamChoker + StreamGobbler). Thread-safe*/
public synchronized void execProc(String cmd) {
// Append an 'ENTER'-key to execute command ( \r\n = ENTER )
String str = cmd + " \r\n";
StreamChoker c = new StreamChoker(str, p.getOutputStream());
c.start();
// Print results on screen.
StreamGobbler s1 = new StreamGobbler(p.getInputStream());
StreamGobbler s2 = new StreamGobbler(p.getErrorStream());
s1.start();
s2.start();
}
}
Klasse StreamChoker
Code:
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class StreamChoker implements Runnable {
/** The output stream of a process to write to the command prompt. */
private final OutputStream os;
private final String cmd;
private Thread thread;
public void start() {
thread = new Thread(this);
thread.start();
}
public StreamChoker(String cmd, OutputStream os) {
this.os = os;
this.cmd = cmd;
}
/**
* Runs the thread. Emit and execute the command to the output stream into the console.
*/
@Override
public void run() {
BufferedOutputStream bos = new BufferedOutputStream(os);
try {
bos.write(cmd.getBytes());
bos.flush();
} catch (IOException e) {
System.err.println("ERR: Invalid entering sequence." + " '" + cmd + "' not be executed." );
System.err.println(e.getMessage());
}
}
}
Klasse StreamGobbler
Code:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class StreamGobbler implements Runnable {
/** The input stream of a process to read the command prompt. */
private final InputStream is;
private Thread thread;
public void start() {
thread = new Thread(this);
thread.start();
}
public StreamGobbler(InputStream is) {
this.is = is;
}
/**
* Runs the thread. Prints the process's input stream on the console.
*/
@Override
public void run() {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String str;
try {
while ((str = br.readLine()) != null) {
System.out.println(str);
}
} catch (IOException e) {
System.err.println("ERR: Invalid reading sequence.");
System.err.println(e.getMessage());
}
}
}