ProcessBuilder Output

TDO88

Grünschnabel
Hallo Zusammen,

folgendes Problem. Ich rufe aus meiner Java Anwendung ein anderes Programm ".exe" auf.
Das externe Programm führt kurz etwas aus und gibt über die Konsole einen String zurück, ob der Vorgang erfolgreich war oder nicht.
Jetzt möchte ich diesen String abfangen und aus meinem Programm heraus auswerten.
Dazu habe ich folgendes versucht:
Java:
ProcessBuilder pBuilder = new ProcessBuilder(SwitchBoardPath,LoadINICommand);
File output = new File("C:\\Users\\TDO\\Desktop\\output.txt");
pBuilder.redirectOutput(output);
Process p = pBuilder.start();

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));

p.waitFor();
                     
StringBuilder response = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
           response.append(line + "\n");
}
bufferedReader.close();

Die Methode pBuilder.redirectOutput(output) funktioniert einwandfrei. Der String wird empfangen und in die Datei geschrieben.
Die Variable response bleibt leider leer.
Wenn der Text in dem Outputfile steht bringt mir das leider nichts. Ich möchte dann nicht wieder die Datei auslesen. Wie komme ich direkt an den String, bzw. wo ist mein Fehler?

Ich schätze auch mal, dass ich eine Möglichkeit finden muss mit der pBuilder Variable den Output abzufangen und nicht mit der Process Variable "p". Aber für die pBuilder gibt es nur die Möglichkeiten redirectOutput() mit Redirect als Rückgabetyp, redirectOutput(File file) mit ProcessBuilder als Rückgabewert und redirectOutput(Redirect destination) ebenfalls mit ProcessBuilder als Rückgabewert.

Hat jemand eine Idee, wie ich das machen kann, bzw. sieht jemand meinen Fehler?

Bin für jede Hilfe dankbar!

Gruß
TDO

Übrigens: Das externe Programm ist eine C Anwendung, welche über cout den Befehl am Ende schickt, den ich benötige. Weiß nicht, ob das von Interesse ist
 
Zuletzt bearbeitet von einem Moderator:

sheel

I love Asm
Hi

das:
Java:
File output = new File("C:\\Users\\TDO\\Desktop\\output.txt");
pBuilder.redirectOutput(output);
widerspricht sich irgendwie mit dem Rest.
Willst du die Ausgabe jetzt in die Datei haben oder in die Variable?

Und das p.waitFor(); ist auch eher kontraproduktiv. Weg damit.

Btw., die Programmiersprache vom anderen Programm sollte keinen Unterschied machen,
aber wenn cout drin vorkommt, ist es wohl C++, nicht C.
 

TDO88

Grünschnabel
Hallo sheel,

danke für die Antwort.
Das mit der Datei habe ich nur mal gemacht, um zu sehen, ob ich überhaupt was zurückbekomme. Die Zeilen sollen rausfliegen, sobald ich den Text in eine Variable bekomme.
Warum ist p.waitFor() kontraproduktiv? Ich muss in meiner Anwendung ja warten, bis das externe Programm fertig ist, bevor ich weitermachen kann.

Btw., die Programmiersprache vom anderen Programm sollte keinen Unterschied machen,
aber wenn cout drin vorkommt, ist es wohl C++, nicht C.

Stimmt... mein Fehler ;)

Macht es einen Unterschied, wenn der String, der vom externen Prozess gesendet wird nicht mit z.B. "\r" abgeschlossen ist?
 
Zuletzt bearbeitet von einem Moderator:

sheel

I love Asm
Also:

Das mit der Datei dürfte wohl einer der Problemgründe sein, weil die Ausgabe dann nur in die Datei geht.

Das waitFor ist
a) sinnlos, weil beim Lesen später ggf. von selbst gewartet wird, bis das Programm mehr ausgibt oder beendet ist
b) ein Fehler, weil jede Ausgabe vorm Lesen irgendwo zwischengespeichert wird, dieser Buffer voll werden kann
und dann das ausgebende Programm wartet, bis es weiterschreiben darf. Da du den Buffer nie leerst,
bevor das Programm nicht beendet ist, wartet ihr gegenseitig bis in alle Ewigkeit.

Wenn die Ausgabe nicht mit einem Zeilenwechsel abgeschlossen ist macht das nichts.
\r allein ist kein Zeilenwechsel, aber stört zumindest bei mir auch nicht (getestet).

Jedenfalls funktioniert es bei mir problemlos, mit folgenden Codes:
C++-Teil:
C++:
#include<iostream>
#include<windows.h>

int main()
{
	std::cout << "AAAA" << std::endl;
	Sleep(4000);
	std::cout << "BBBB";
}
4 Sekunden Sleep, um dann sehen zu können, dass das Javaprogramm beim Einlesen
auch ohne waitFor mitwartet, außerdem einmal mit Zeilenwechsel und einmal ohne
(\r ist hier nicht drin, hab ich aber wie gesagt auch probiert. Geht problemlos)

Java-Teil:
Java:
package df;

import java.io.*;
import java.util.*;

public class Main {
	public static void main(String[] args) {
		try {
			ProcessBuilder pBuilder = new ProcessBuilder("a.exe");
			Process p = pBuilder.start();
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
			StringBuilder response = new StringBuilder();
			String line;
			while ((line = bufferedReader.readLine()) != null) {
				response.append(line + "\n");
			}
			bufferedReader.close();
			System.out.println(response.toString());
		} catch(Exception eee) {
			System.out.println(eee.toString());
		}
	}
}
 

TDO88

Grünschnabel
Hab in der externen Anwendung jetzt einmal ein "\n" am Ende der Zeile eingefügt -> immernoch nichts zu lesen und nochmal ein "\r" -> genauso...
Hat sonst noch jemand eine Idee, was ich probieren kann? ich werd hier noch wahnsinnig...

Das mit der Datei dürfte wohl einer der Problemgründe sein, weil die Ausgabe dann nur in die Datei geht.

Ich werd bekloppt! Genau das war das Problem! Er hat den String in die Datei geschrieben und dadurch war er wohl für die InputStreamReader nicht mehr da.... die Zeile für den Datei redirect gelöscht und schon bekomme ich, was ich wollte!! Vielen, vielen Dank!
Sau blöder Fehler
 
Zuletzt bearbeitet von einem Moderator: