Eigene Klasse für externe Befehle - Warten auf Prozesse

guni

Bekanntes Mitglied
Hallo,

in meinem java-Programm rufe ich öfters externe Befehle auf.
Da ich in der Hauptlogik meines Programmes die Übersicht behalten will, habe ich eine eigene Klasse cmd geschrieben.
Sie sieht so aus:
Java:
public abstract class Cmd extends LinkedList<String> {

	private static final long serialVersionUID = 1L;
	private BufferedReader stdin = null;
	private BufferedReader stderr = null;
	private Runtime runtime = null;

	// fügt angegebenes Command als ersten Listeneintrag von self hinzu
	// Fehler wenn Befehl nicht existiert; d.h. unter Win nicht als
	// <HOME>\bin\<BEFEHL>.exe bzw. unter Linux nicht als /bin/<BEFEHL>
	// zu finden ist
	public Cmd(Runtime r, String cmd) throws Exception {
		super();
		File command = new File(getSysPath(), cmd + getExt());
		if (!command.exists()) {
			throw new Exception("Fehler: Befehl nicht gefunden; "
					+ command.getAbsolutePath());
		}
		add(command.getAbsolutePath());
		runtime = r;
	}

	public BufferedReader getStdin() throws Exception {
		if (stdin == null) {
			throw new Exception(
					"Kristischer Programmfehler: "
							+ "Das Programm versucht den InputStream eines Prozesses zu lesen, "
							+ "der noch nicht gestartet wurde");
		}
		return stdin;
	}

	public BufferedReader getStderr() throws Exception {
		if (stderr == null) {
			throw new Exception(
					"Kristischer Programmfehler: "
							+ "Das Programm versucht den ErrorStream eines Prozesses zu lesen, "
							+ "der noch nicht gestartet wurde");
		}
		return stderr;
	}

	// gibt einen vollständigen Befehl aus
	public void dump() {
		Iterator<String> i = iterator();
		while (i.hasNext()) {
			System.out.println(i.next());
		}
	}

	// führt einen Befehl in der Runtime aus
	// die p.waitFor muss nach Verarbeiten der Streams eingebaut werden
	protected Process run(File workingdir) throws Exception {
		if (runtime == null) {
			throw new Exception("Kritischer Programmfehler: "
					+ "Befehl konnte nicht ausgeführt werden, da Runtime "
					+ "nicht initialisiert ist.");
		}
		Process p = runtime.exec(this.toArray(new String[0]), null, workingdir);
		stdin = new BufferedReader(new InputStreamReader(p.getInputStream()));
		stderr = new BufferedReader(new InputStreamReader(p.getErrorStream()));
		return p;
	}
	
	// wenn mehr als der eigentliche Befehl vorhanden ist, dann alles an
	// Zusatzeinträgen wieder weg
	protected void rmparams() {
		if (this.size() > 1) {
			String entry = this.removeFirst();
			this.clear();
			this.add(entry);
		}
	}

	protected void printStream(BufferedReader r) throws IOException {
		String line = "";
		while ((line = r.readLine()) != null) {
			System.out.println(line);
		}
	}

	// gibt für Linux /bin zurück
	// gibt für windows <HOME>/bin zurück
	// Fehler wenn,
	// Betriebssystem weder Windows noch Linux
	// keine HOME-Umgebungsvariable gesetzt ist (wo /bin/cmd zu finden ist)
	// /bin oder <HOME>\bin am System nicht existiert
	// /bin oder <HOME>\bin kein Directory ist
	protected File getSysPath() throws Exception {
		File path = null;

		String home = System.getenv("HOME");
		home = "C:\\cygwin"; // TODO: nur für Testfälle
		if (home == null) {
			throw new Exception(
					"Fehler: Commands können nicht initialisiert werden, "
							+ "da keine Home-Variable gefunden wurde. "
							+ "Command muss evt. unter <HOME>/bin zu finden sein");
		}

		if (OsValidator.isUnix()) {
			path = new File("/bin");
		} else if (OsValidator.isWindows()) {
			path = new File(home + "\\bin\\");
		} else {
			throw new Exception("Fehler: Unbekanntes Betriebssystem");
		}

		if (!path.exists()) {
			throw new Exception(
					"Fehler: Command kann nicht initialisiert werden, "
							+ "da angegebener Syspath nicht existiert: "
							+ path.getAbsolutePath());
		}

		if (!path.isDirectory()) {
			throw new Exception(
					"Fehler: Command kann nicht initialisiert werden, "
							+ "da angegebener Syspath kein Verzeichnis ist: "
							+ path.getAbsolutePath());
		}

		return path;
	}

	// gibt für Linux "" zurück
	// gibt für Windows ".exe" zurück
	// Fehler wenn Betriebssystem weder Windows noch Linux
	protected String getExt() throws Exception {
		if (OsValidator.isUnix()) {
			return "";
		} else if (OsValidator.isWindows()) {
			return ".exe";
		} else {
			throw new Exception("Fehler: Unbekanntes Betriebssystem");
		}
	}

}

die Klasse ist abstrakt; ich kann aber nun für verschiedene Befehle einfache Klassen bauen; z.B. der gzip-Befehl:
Java:
public class Gzip extends Cmd {

	private static final long serialVersionUID = 1L;

	public Gzip(Runtime r) throws Exception {
		super(r, "gzip");
	}
	
	public void zip(File f) throws Exception {
		super.rmparams();
		add(f.getAbsolutePath());
		run(new File("."));
	}
	
	public void unzip() {
		super.rmparams();
		add("-d");
		// ...
	}

}

jetzt hab ich aber noch ein Problem mit meiner run-Methode.
Und zwar hab ich gelesen, dass die Methode Process.waitFor irgendwie nur dann funktioniert, wenn alle InputStreams eines externen Programms "abgearbeitet" wurden.

ich schreibe also statt
Java:
run(new File("."))
Java:
Process p = run(new File("."));
		printStream(super.getStdin());
		printStream(super.getStderr());
		p.waitFor();
... trotzdem "hängt sich mein Programm auf" - woran kann das liegen?!

mfg, guni
 

FArt

Top Contributor
... trotzdem "hängt sich mein Programm auf" - woran kann das liegen?!
Weil der Thread, der bei dir die Streams auslesen soll, auf das Ende des Prozesses wartet. Lese die Streams in einem extra Thread aus, der nicht blockierend wartet.
 

guni

Bekanntes Mitglied
aber ich möchte doch warten!
bevor ich meinen gzip starte will ich, dass der tar vollständig abgeschlossen ist!
und wie mache ich das denn, dass ich streams in einem extra thread auslese?!

PS.: @FArt: ich such mal nach einem brainfuck compiler ;-)
 

FArt

Top Contributor
Du brauchst für jeden Stream, den du konsumieren möchtest, einen eigenen Thread, der nebenläufig die Daten ausliest, während der forkende Thread auf das Ende des Prozesses wartet.
 

FArt

Top Contributor
In der Zwischenzeit hättest du es probieren können selbst eine Lösung zu erarbeiten und bei Bedarf mit einem konkreten Problem wieder hier aufschlagen können.

Oder worin besteht dein Problem? Sowohl für Streams, als auch für Threads oder das java.util.concurrent Packagage gibt es Tutorials und Dokumentationen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
D Klassen Eigene Klasse für ArrayList Java Basics - Anfänger-Themen 6
J Eigene Klasse für die Variablen? Java Basics - Anfänger-Themen 3
F Eigene Klasse für die Keys von HashMap Java Basics - Anfänger-Themen 5
T Konstruktor für eigene Klasse erstellen Java Basics - Anfänger-Themen 6
F Eigene Klasse für Events Java Basics - Anfänger-Themen 10
L eigene Klasse für DB Java Basics - Anfänger-Themen 5
Amina556 Eigene Klasse definieren Java Basics - Anfänger-Themen 9
L Meine erste eigene Exception Klasse Java Basics - Anfänger-Themen 10
D Attribut Telefonnummer - eigene Klasse oder String Java Basics - Anfänger-Themen 13
S Eigene LinkedList Klasse Java Basics - Anfänger-Themen 4
H Klassen auf eigene Klasse zugreifen Java Basics - Anfänger-Themen 2
B Klassen Eigene "non static" Klasse in Main verwenden! Java Basics - Anfänger-Themen 12
S Wann existiert eine Instanz (eigene Klasse) Java Basics - Anfänger-Themen 8
S Eigene Exception Klasse - fehlender Konstruktor mit String Java Basics - Anfänger-Themen 3
B eigene klasse in listen eintragen Java Basics - Anfänger-Themen 6
A Objekte in eigene Klasse auslagern Java Basics - Anfänger-Themen 2
Kenan89 ActionListener in eigene Klasse Java Basics - Anfänger-Themen 8
E Object in eigene Klasse umwandeln? Java Basics - Anfänger-Themen 7
F Klassen Eigene Klasse definieren Java Basics - Anfänger-Themen 4
T eigene Exception Klasse Java Basics - Anfänger-Themen 12
G Eigene Klasse als Array, zugriff? Java Basics - Anfänger-Themen 2
S Eigene Stack Klasse Java Basics - Anfänger-Themen 26
W GUI als eigene Klasse oder in die Startklasse? Java Basics - Anfänger-Themen 21
H Buttonbefehle in eigene Klasse schreiben Java Basics - Anfänger-Themen 8
nrg Eigene simple List-Klasse programmieren Java Basics - Anfänger-Themen 3
M eigene Property-Klasse Java Basics - Anfänger-Themen 2
L Aus einer Methode eine eigene Klasse machen - modular coden Java Basics - Anfänger-Themen 14
E Eigene Stack Klasse schreiben Java Basics - Anfänger-Themen 12
M Eigene Klasse mit "Enumeration"-Datentyp verknüpfe Java Basics - Anfänger-Themen 16
B eigene Klasse wird nicht im Hauptprogramm erkannt! Java Basics - Anfänger-Themen 4
U Eigene klasse schreiben Java Basics - Anfänger-Themen 13
A meine eigene IO Klasse Java Basics - Anfänger-Themen 3
G Vererbung: Methoden die eigene Klasse zurückgeben Java Basics - Anfänger-Themen 8
B Panel mit Radiobuttons als eigene Klasse Java Basics - Anfänger-Themen 4
E Eigene Klasse erstellen? Java Basics - Anfänger-Themen 21
D Eigene Klasse als Import Java Basics - Anfänger-Themen 10
M eigene klasse definieren und verfügbar machen Java Basics - Anfänger-Themen 9
T Eigene Exception - ohne werfen abfangen Java Basics - Anfänger-Themen 2
T Datentypen Eigene Datentypen Java Basics - Anfänger-Themen 15
low_in_the_head Eigene Exception nutzen Java Basics - Anfänger-Themen 4
C Archiv für eigene Klassen Java Basics - Anfänger-Themen 9
B JUnit 4: Wie man die eigene Liste testen kann [TDD] Java Basics - Anfänger-Themen 46
C eigene Methoden erstellen (Instanzmethoden) Java Basics - Anfänger-Themen 7
I Eigene Java Tools Nutzung Java Basics - Anfänger-Themen 6
G eigene Bibliothek einbinden Java Basics - Anfänger-Themen 1
K Eigene Annotations, Pre-/Post-/Call-Method Java Basics - Anfänger-Themen 6
O Erste Schritte Eigene charAt(i) Methode schreiben Java Basics - Anfänger-Themen 10
D Methoden Eigene Methode um alle Ausgaben aufzurufen Java Basics - Anfänger-Themen 17
L Eigene Exception schreiben bei zu langem Array Java Basics - Anfänger-Themen 10
P Maven und eigene Jars Java Basics - Anfänger-Themen 4
J Algorithmus - Strings auf eigene Reihenfolge miteinander vergleichen Java Basics - Anfänger-Themen 4
R Interface Eigene Objekte in Listen sortieren mit Interface Comparable Java Basics - Anfänger-Themen 5
A Eigene Methoden entwicken Java Basics - Anfänger-Themen 3
F Klassen Eigene Exception Bedingungen festlegen Java Basics - Anfänger-Themen 2
H GSON-Bibliothek für eigene Programme benutzen Java Basics - Anfänger-Themen 2
N Eclipse - eigene Icons unter ClassPath Resource Java Basics - Anfänger-Themen 0
N Eigene Stream Methoden implementieren Java Basics - Anfänger-Themen 3
R eigene Graphikbedienelemente Java Basics - Anfänger-Themen 8
V Generics / eigene Liste Java Basics - Anfänger-Themen 4
T Eigene Bedingung in IF-Bedingung Java Basics - Anfänger-Themen 22
P Java 8 & Eigene Applets Java Basics - Anfänger-Themen 3
E Best Practice Exaktes Rechnen mit (Pseudo-)Rationalen/Realen Zahlen. Operations Zuweisung für (eigene) Klassen Java Basics - Anfänger-Themen 3
G eigene Bibliothek in Java importieren Java Basics - Anfänger-Themen 5
M Wann eigene implementierte HashCode Methode zwingend erforderlich? Java Basics - Anfänger-Themen 1
P Vererbung Eigene HashMap Variante Java Basics - Anfänger-Themen 2
P Eigene Knöpfe mit eigenem Listener Java Basics - Anfänger-Themen 5
T Muss ein Parametertest immer eine eigene Testklasse sein? Java Basics - Anfänger-Themen 3
B Multithreading und eigene Queue entwickeln Java Basics - Anfänger-Themen 3
O GUI: Eigene Fenster "Form"? Java Basics - Anfänger-Themen 13
F Eigene LinkedList - toString Java Basics - Anfänger-Themen 10
O Denkanstöße für eigene Konfigurations-Datei Java Basics - Anfänger-Themen 12
SexyPenny90 Wieso ist diese eigene Equals-Methode schlecht? Java Basics - Anfänger-Themen 17
C eigene Exception Java Basics - Anfänger-Themen 4
M externe JARs in die eigene JAR einbinden Java Basics - Anfänger-Themen 9
V Klassen import - einfaches Umleiten auf eigene Klassen? Java Basics - Anfänger-Themen 8
S [JavaFX 2.1] - Eigene Sprachauswahl? Java Basics - Anfänger-Themen 4
K Klassen Eigene Exception verwenden Java Basics - Anfänger-Themen 9
J eigene packages bzw klassen verwenden Java Basics - Anfänger-Themen 25
E Eigene Stackklasse Java Basics - Anfänger-Themen 7
B Eigene Exceptions entwerfen Java Basics - Anfänger-Themen 3
S Eigene Exception Schreiben und Welche Auslösen wie ? Java Basics - Anfänger-Themen 7
P eigene kleine Datenverwaltung Java Basics - Anfänger-Themen 5
N Eigene Methoden-> Werte übergeben Java Basics - Anfänger-Themen 5
U Klassen Eigene Klassen importieren Java Basics - Anfänger-Themen 13
S Eigene Klassen addieren Java Basics - Anfänger-Themen 3
B OOP Eigene Objekte in Arrays zusammenfassen Java Basics - Anfänger-Themen 3
E Eigene class datum Java Basics - Anfänger-Themen 2
G Eigene MessageBox kreieren Java Basics - Anfänger-Themen 9
I Erste Schritte Eigene Fehlermeldungen bei Exceptions Java Basics - Anfänger-Themen 19
S Eigene KeyEvent-Mask erstellen Java Basics - Anfänger-Themen 4
X Eigene Libary Java Basics - Anfänger-Themen 2
Crashbreaker Eigene Java-Programm ohne hilfe des CMD starten Java Basics - Anfänger-Themen 11
A Klassen Eigene Datenklasse - Strings mit fixer Länge Java Basics - Anfänger-Themen 2
G Shape um eigene Achse drehen Java Basics - Anfänger-Themen 2
P Vererbung Basisklasse soll eigene Methode benutzen Java Basics - Anfänger-Themen 38
J Eigene kleine Datenbank programmieren Java Basics - Anfänger-Themen 2
xehpuk Ordner "Eigene Bilder" ansteuern Java Basics - Anfänger-Themen 3
V Sonderzeichen als eigene "Operatoren" im JTextField Java Basics - Anfänger-Themen 4
D Eigene equals methode schreiben Java Basics - Anfänger-Themen 4
dataframe OOP Eigene typisierte Liste Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben