# OutputStream to System.out



## guni (30. Jan 2009)

hallo,

ich würde gern das result von process.getOutputStream auf der Console ausgeben.
wie mach ich das?

lg, guni


----------



## The_S (30. Jan 2009)

System.setOut(new Printstream(deinOutputStream));


----------



## guni (2. Feb 2009)

hmm ...
ich bekomm keinen output stream. hab mehrere Prozesse (und Operationen innerhalb eines Prozesses) ausprobiert; es is aber keine "Reaktion gekommen". ich rufe meine Funktion


> public void instructSomeWork(String[] foreigner) throws IOException, InterruptedException {
> Process p = Runtime.getRuntime().exec(foreigner);
> PrintStream ps = new PrintStream(p.getOutputStream());
> System.setOut(ps);
> ...


zum Beispiel mit


> obj.instructSomeWork(new String[]{"notepad.exe"});


auf.
ich bekomm aber keinen Output in der Konsole. Kann es tatsächlich sein, dass dieser Prozess in keinem Fall einen Output gibt?!

lg, guni


----------



## The_S (2. Feb 2009)

ja!?


----------



## guni (2. Feb 2009)

hmm ...
meine setup.exe erzeugt ja wie gesagt einen neuen Prozess und beendet sich dann.
mein ziel ist nach wie vor, den neuen prozess "abzufangen" und das "wait" um diesen prozess zu erweitern. ich hatte gehofft, dass ich einen Output erhalte wo ich irgendwas mit "starting new process with PID ..." abfangen könnt und irgendwie darauf reagieren könnte ... scheint so auch nicht zu gehen, oder? Gibt es irgendwelche anderen Vorschläge?!

mfg, guni


----------



## The_S (2. Feb 2009)

guni hat gesagt.:
			
		

> hmm ...
> meine setup.exe erzeugt ja wie gesagt einen neuen Prozess und beendet sich dann.



Wie gesagt? Davon höre ich jetzt zum ersten Mal. Was ist deine "setup.exe"? Installer für dein Programm auf Windows-Systemen?



			
				guni hat gesagt.:
			
		

> mein ziel ist nach wie vor



nach wie vor? Höre ich jetzt auch zum ersten Mal :roll:



			
				guni hat gesagt.:
			
		

> den neuen prozess "abzufangen" und das "wait" um diesen prozess zu erweitern.



Versteh ich nicht. Was meinst du mit "prozess abfagnen" und in welcher Sicht möchtest du "wait erweitern"?



			
				guni hat gesagt.:
			
		

> gehofft, dass ich einen Output erhalte wo ich irgendwas mit "starting new process with PID ..." abfangen könnt und irgendwie darauf reagieren könnte ..



Wenn das Programm sowas nicht schreibt, dann nicht. Das was du über den OutputStream bekommst, ist das, was das andere Programm über sowas wie System.out.println ausgeben würde.



			
				guni hat gesagt.:
			
		

> Gibt es irgendwelche anderen Vorschläge?!



Vielleicht - wenn du ein bisschen konkreter wirst.


----------



## guni (2. Feb 2009)

@Hobbit im Blutrausch ...

sorry - hab das Thema verwechselt. Ich hab schon einen anderen Post zu dem Thema aufgemacht und dann noch einen mit einem Teilproblem. Deswegen mein "wie gesagt" ...
also, das problem ist, dass ich eine Installation in Java automatisieren möchte.
ich habe dazu ein setup.exe die ich mit runtime.exec() aufrufen möchte und dann warten will, bis sie fertig ist. das problem ist: die setup.exe ist gleich mal fertig; mein setup aber noch lange nicht. die setup.exe ruft nämlich eine weitere exe auf, die dann ein paar dateien entpackt und letzten endes einen javaw-prozess startet, der dann das eigentliche Setup des Programmes durchführt.

Meine aufgabenstellung: die setup.exe starten und das programm dann solange warten lassen, bis der javaw-prozess fertig is :-(


----------



## The_S (2. Feb 2009)

Hast du Zugriff auf das ausgeführte Java-Programm?


----------



## guni (2. Feb 2009)

was genau meinst du mit "zugriff"? ich hab admin rechte am rechner, ja ...
das ganze is halt ein hintergrundprozess und mir fehlt der ansatz, wie ich aus java darauf zugreifen soll!


----------



## The_S (2. Feb 2009)

Ich meinte eher, ob du es verändern kannst. Z. B. ne Datei anlegen, wenn es fertig ist. Oder ne Nachricht an nen bestimmten Port schicken ...

ansonsten wüsste ich auch keine Möglichkeit.


----------



## guni (2. Feb 2009)

hmm ... nein. kann ich an und für sich nicht. aber wenn ich es könnte, dann müsste ich in mein java programm einen eventlistener einbauen, der darauf reagiert, wann eine bestimmte datei angelegt wurde, oder?! und damit müsste ich in die windows-api und nach einem createFile event schaun. und wenn ich das mache, dann könnte ich doch gleich einen eventlistener auf einen createProcess schreiben. geht sowas? gibt es in windows so ein event?
btw: ich bin java anfänger *gg*

lg, guni


----------



## guni (2. Feb 2009)

hallo,

habe jetzt versucht, den output eines prozesses an system.out zu übergeben.
diesmal bin ich mir sicher, dass der prozess einen output hat:


```
public void output() throws IOException {
		Process p = Runtime.getRuntime().exec(new String[]{"ps.exe","-A"});
		System.setOut(new PrintStream(p.getOutputStream()));
	}
```

trotzdem sehe ich kein Ergebnis. woran kann das liegen?!
muss ich meine set-out VOR dem exec aufrufen? wenn ja, wie komme ich dann auf den prozess?!

lg, guni


----------



## SlaterB (2. Feb 2009)

hmm, verstehen hier eigentlich alle, was die Aufgabe ist?

p.getOutputStream()
ist ein Stream, der den Output deines Programmes an das andere darstellt,

da kommt nur genau dann was rein, wenn das aufrufende Java-Programm etwas schreibt,
beispielesweise würde nun mit neuem Out
System.out.println("Test"); nicht mehr auf dem Bildschirm erscheinen sondern beim Process p den Input darstellen


ist es nicht genau andersrum erwünscht, den InputStream von Process p, also das was der so alles schreibt, 
im aufrufenden JavaProgramm auszugeben?
das wäre ein ganz anderer Code, siehe mein Programm in
http://www.java-forum.org/de/viewtopic.php?t=81971

vielleicht verstehe aber nur ich alles falsch


----------



## The_S (2. Feb 2009)

Wäre natürlich auch möglich. Also ich blick ehrlich gesagt auch nicht so wirklich durch.


----------



## guni (2. Feb 2009)

*gg* nein - ich denke, *mir* geht langsam ein Licht auf.
habe mir dein programm jetzt durchgeschaut. das problem ist: bei mir funktioniert es trotzdem nicht;
irgendwie schein ich in eine endlosschleife zu kommen und es wird gar nichts ausgegeben.
ich hab mir mal ein programm mit schön viel output hergenommen:


```
Process p = Runtime.getRuntime().exec(new String[]{"wmic","process","list"});
		BufferedReader pin = new BufferedReader(new InputStreamReader(p.getInputStream()));
		String line = null;
		while ((line = pin.readLine()) != null){
			System.out.println("line: " + line);
		}
		pin.close();
```

... wie gesagt: nur endlosschleife. woran kann das liegen?!

lg, guni


----------



## guni (2. Feb 2009)

ich hab getOutputStream und getINputStream verwechselt!


----------



## SlaterB (2. Feb 2009)

in dem Code taucht doch gar kein OutputStream auf, bzw. aus einem OutputStream kann man auch gar nicht lesen,
schwer zu verwechseln..
naja, du meinst wohl was anderes in deinem Programm,

ist aktuell noch was offen?


----------



## guni (3. Feb 2009)

ja ... nochmal: ich habe einen befehl; z.B. "wmic process list" ... sobald mein betriebssystem am rennen ist, kann ich garantieren, dass dieser befehl einen output gibt ;-)
jetzt rufe ich exakt den gleichen befehl in java auf; mit einem Runtime.execute.
dann versuche ich das, was normalerweise ausgegeben wird zeilenweise einem String zuzuweisen und mit System.out auszugeben.


```
Process p = Runtime.getRuntime().exec(new String[]{"wmic","process","list"});
      BufferedReader pin = new BufferedReader(new InputStreamReader(p.getInputStream()));
      String line = null;
      while ((line = pin.readLine()) != null){
         System.out.println("line: " + line);
      }
      pin.close();
```

ich bekomme hier aber keinen output; stattdessen nur eine endlosschleife. mein programm unterscheidet sich im ansatz eigentlich nicht von dem programm, dass slaterB in einem vorherigen Post verlinkt hat. trotzdem: es funktioniert nicht. woran kann das liegen?


----------



## SlaterB (3. Feb 2009)

bekommst du eine Ausgabe
line:
line:
line:
line:
line:

oder gar keine Ausgabe?
schaust du auch in den ErrorStream?
bei einer Endlosschleife allerdings schwierig.., vielleicht in einem Extra-Thread oder in einer Schleife abwechselnd in beide Streams reinschauen


----------



## guni (3. Feb 2009)

nein, zur zeit bekomme ich gar keine ausgabe.
ich werde mir den error thread mal separat anschauen. das thread-konzept überfordert mich im moment vollkommen! wie könnte ich denn sowas realisieren?


----------



## guni (3. Feb 2009)

... ich bekomme auch beim getErrorStream eine Endlosschleife :-(


----------



## SlaterB (3. Feb 2009)

was dich überfordert, will ich gar nicht erst ansprechen 

wie kommst du denn ohne Ausgabe zu der Annahme, dass eine Endlosschleife vorliegt?
vielleicht meinst du, dass das Programm blockiert, das wäre nicht verwunderlich, falls es nicht von selber aufhört,
oder hört es auf der Konsole sofort wieder auf?


----------



## guni (3. Feb 2009)

hmm ... es scheint sich doch nicht um eine endlosschleife zu handeln
wenn ich mit dem eclipse durchgehe, sehe ich, dass mein programm beim pin.readLine() "hängenbleibt"


----------



## guni (3. Feb 2009)

ok ... ich glaub das prinzip vom thread hab ich jetzt so mehr oder weniger geschnallt.
da geht es einfach darum, dass mehrere programmteile gleichzeitig gestartet werden;
d.h.
das programm geht nach einem thread.start() - Aufruf gleich in die nächste Zeile und führt das, was Thread.start aufruft "nebenbei" oder "simultan nebenbei" aus ... kann das sein?!

na ja - wie Object.wait und die notify-Methode da mit reinspielen check ich leider trotzdem noch nicht ganz; in erster linie wär's mir aber sowieso mal wichtig, den Stream von meinem Prozess zu "finden" *heul*


----------



## thE_29 (3. Feb 2009)

Ich würde davon abraten diese Streams zu verwenden!

Am besten den Output in eine Datei umleiten lassen und diese dann auslesen.

Weil nach gewisser Zeit/Länge hängt sich der Buffer sowieso auf.. (istn Java Bug)


----------



## guni (3. Feb 2009)

hallo thE_29.
hmm ... danke für den tipp. ich weiß aber, dass mein konsolenoutput nicht größer als 4-5 Zeilen wird ... soll ich trotzdem in eine Datei umleiten?! das macht für mich wenig Sinn!
hast du vielleicht eine Idee, warum ich keine Ausgabe bekomme? 
Der Stream enthält ja eigentlich nicht viele Daten!

mfg, guni


----------



## thE_29 (3. Feb 2009)

Wie gesagt, ich würde es immer in eine Datei umleiten lassen..

Meiner Meinung nach bringt funktioniert das auslesen der Streams nicht zu 100% und somit nutze ich es auch nicht (weil die SW immer zu 100% funktionieren sollte)


----------



## guni (3. Feb 2009)

es funktioniert nicht zu 100%?!
meinst du, dass du nicht den vollständigen Output zurückbekommst, oder dass du eben overflows bekommen kannst?!
overflows wären mir eher wuscht weil ich - wie gesagt - nichtmal in den Kilobytebereich kommen würde ...
mein problem ist aber nach wie vor weniger das konzept sondern eher, dass ich einfach gar keinen output bekomm! woran kann das liegen und wie kann ich in einer datei umleiten? denkst du da an ein runtime.exec("BEFEHL > DATEI") oder gibt es da noch was anderes?!

mfg, guni


----------



## thE_29 (3. Feb 2009)

Jo, umleiten ist mit >!

Und zu 100% bezieht sich darin, dass es sich mal früher mal später aufhängen kann...

Am besten mit File.createTmpFile eine temporäre Datei erzeugen lassen und dann dort umleiten lassen!

Eventuell noch 2>&1 sagen, damit der ErrorStream auch in die gleiche Datei kommt.

Also: "binary.exe > " + File.createTmpFile() + " 2>&1"


----------



## guni (3. Feb 2009)

@thE_29. ich bin verzweifelt! es funktioniert immer noch nicht.
was ist da an meinem code so falsch?!


```
File consoledmp = File.createTempFile("console",".dmp");
		Process p = Runtime.getRuntime().exec(new String[]{"wmic","process","list","2>&1>",consoledmp.toString()});
		BufferedReader in = new BufferedReader(new FileReader(consoledmp));
		String line = null;
		while ((line = in.readLine()) != null)
			System.out.println("line: " + line);
		in.close();
```

mfg, guni


----------



## thE_29 (3. Feb 2009)

Sag mal


```
Runtime.getRuntime().exec("wmic process list > " + consoledmp.getAbsolutePath() + " 2>&1");
```

Das mit den Parametern im Array übergeben ist auch so ne Geschichte die nicht zu 100% klappt 
Und ob das umleiten überhaupt als Parameter geht, wage ich zu bezweifeln.

Desweiteren würde ich noch ein waitFor machen, sodaß er wartet bis der wmic terminiert (maybe war das schon immer dein Problem). Da bei langsamen PCs wmic ne Zeitlang braucht..


Nachtrag: OK, da hat es was mit diesem wmic! Der Prozess beendet sich ja einfach nicht...


----------



## SlaterB (3. Feb 2009)

wenn es auch noch eines der Programme ist, die ständig die Konsole aktualisieren, 
dann schreibt es vielleicht gar nicht in so einen simplen Stream,
aber das ist Spekulation von mir


----------



## thE_29 (3. Feb 2009)

Man kann auch via /OUTPUTateiname eine Datei angeben!

Aber auch das hilft nix.. Der Prozess wmic beendet sich erst nachdem man Java beendet hat (WTF?!?!).

Selbst wenn ich das ganze in einer Bat Datei starte, ändert sich nix. Starte ich die bat Datei per Hand funktionierts...


----------



## thE_29 (3. Feb 2009)

So, mit dem hier gehts:


```
File consoledmp = File.createTempFile("console",".dmp");

    Runtime.getRuntime().exec("cmd /c start wmic /OUTPUT:" + consoledmp.getAbsolutePath() + " process list status").waitFor();
    Thread.currentThread().sleep(1500);
    BufferedReader inStream = new BufferedReader(new FileReader(consoledmp));
    String line = null;
    while ((line = inStream.readLine()) != null)
      System.out.println("line: " + line);
    inStream.close();
```

Irgendwie hängt wmic wenn es einen Elternprozess hat auf diesem Prozess..
Keine Ahnung warum..
Leider geht dann das waitFor nicht mehr und wenn wmic lange braucht, dann ist die Datei leer oder du kriegst ne Exception..


----------



## SlaterB (3. Feb 2009)

oh,  das ist ein Windows-Prozess? 

> Thread.currentThread().sleep(1500); 

tztz, statische Methode


----------



## guni (3. Feb 2009)

maaan! warum gibt so ein blöder prozess nicht einfach ein exit event zurück oder so, dann wär das Ganze viel einfacher!
vielleicht schau ich mir wirklich JNA noch an ...


----------

