2 Stimmen

Führen Sie einen externen Prozess von Java aus. Erhalten Sie die Ausgabe nach Beendigung des Prozesses, benötigen Sie sie jedoch vor der Beendigung.

Warum erhalte ich die Ausgabe des Prozesses erst, nachdem der Prozess beendet ist? Ich möchte die Prozessausgabe "live" erhalten, während der Prozess läuft und nicht nachdem der Prozess beendet wurde. Ich möchte einen Prozess wie einen JBoss ausführen, der die Protokollierung auf der Standardausgabe durchführt, daher benötige ich diese Informationen rechtzeitig und nicht nachdem der Prozess beendet wurde. Danke für Antworten.

Hier ist mein Code:

        try {
        process = processBuilder.start();
        processOutput = process.getOutputStream();
        processInput = process.getInputStream();
        processReader = new BufferedReader(new InputStreamReader(
                processInput));
        processWriter = new BufferedWriter(new OutputStreamWriter(
                processOutput));

        while ((line = processReader.readLine()) != null) {
            System.out.println(line);
          }
        processReader.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

Erweiterung:

Also möchte ich ein externes Programm von einem Eclipse-Plug-In mit einem Button starten. Wenn ich auf den Button klicke, startet das Programm und die Ausgabe des externen Programms wird in die Konsole zurückgelangen. Wenn ich auf "stop" klicke, wird das Programm gestoppt. Hier ist, wie ich die Instanz des Prozess-Erstellungsprogramms erstelle. Und ich habe eine Beispielklasse erstellt, um das Prozess-Erstellungstool ohne den Start des gesamten Plugin-Projekts bei jeder Änderung zu testen.

Hier ist meine Prozess-Erstellungsinstanz, die Runnable implementiert:

@Override
public void run() {
    List command = new ArrayList();
    command.add(serverPath);
    command.add(String.valueOf(count));
    command.add(filePath);
    processBuilder = new ProcessBuilder(command);
    processBuilder.redirectErrorStream(true);

    try {
        process = processBuilder.start();
        processOutput = process.getOutputStream();
        processInput = process.getInputStream();
        processReader = new BufferedReader(new InputStreamReader(
                processInput));
        processWriter = new BufferedWriter(new OutputStreamWriter(
                processOutput));

        System.out.println(process.waitFor());
        while ((line = processReader.readLine()) != null) {
            System.out.println(line);

        }
        processReader.close();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

Die Parameter werden im Konstruktor übergeben. Und hier ist die Instanziierung:

public static void main(String[] args) throws Exception

{

 SimulationProcess smp = new SimulationProcess(count, "file",
            "program_name");
    smp.run();

}

4voto

Es gibt ein paar Dinge, die Sie versuchen können, um Ihr Problem zu lösen:

a) Erstellen Sie ein Testprogramm und führen Sie es mit Ihrem obigen Code aus, um sicherzustellen, dass Sie es richtig lesen können. Zum Beispiel:

public static void main(String[] args) {
  for(;;) {
    try {
      Thread.sleep(5000);
      System.out.println("Testausgabe");
    } catch(InterruptedException e) {
      // Ignorieren
    }

  }
}

b) Stellen Sie sicher, dass Sie den Fehlerstrom des Prozesses behandeln - der Prozess kann blockieren, wenn Sie den Fehlerstrom nicht behandeln. Schauen Sie sich diese Seite für ein Tutorial zu den Dingen, die man vermeiden sollte, wenn man Java's ProcessBuilder oder Runtime.exec() verwendet. Es enthält eine Implementierung eines StreamGobblers, der alle Daten auf einem Stream verwirft, die Sie nicht interessieren.

c) Versuchen Sie System.out.flush() zu verwenden - es könnte sein, dass Ihre Ausgabe zwischengespeichert wird.

EDIT: Danke für das Update. Ihr Problem liegt hier:

System.out.println(process.waitFor()); // Wartet darauf, dass der Prozess beendet wird.
while ((line = processReader.readLine()) != null) {
    System.out.println(line);
}

Wenn Sie das waitFor() entfernen, wird es weiterhin drucken, bis der Strom geschlossen wird. Der Strom sollte nur schließen, wenn der Prozess stirbt. Sie sollten das waitFor() nach der Schleife einfügen?

0voto

Daniel Punkte 2969

Vielleicht enthält Ihre Ausgabe kein Zeilenumbruchszeichen. Auf diese Weise wird Ihre while-Schleife erst dann etwas tun, wenn der Prozess beendet ist.

Versuchen Sie es mit einer anderen Lese-Methode, die nicht auf ein Zeilenumbruchszeichen wartet, zum Beispiel:

char[] cbuf = new char[10];
while(processReader.read(cbuf) != -1)
{
  System.out.print(cbuf);
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X