Konsolen-Output auffangen (Capturing Console Output)



  • Hallo,

    als Antwort auf die Frage von Besucher im Thread http://www.c-plusplus.net/ubb/cgi-bin/ultimatebb.cgi?ubb=get_topic&f=16&t=000456 möchte ich auf das Thema "Capturing Console Output" zu sprechen kommen und das folgende Beispiel hier einfügen. Für Ideen und Kritik bin ich dankbar [img]images/smiles/icon_smile.gif[/img]

    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    import javax.swing.*;
    
    /** Klasse, die ausschließlich static-Methoden beinhaltet um Programmausgabe
     * zu sichern.
     * @author  Cengiz Sahin, 2002
     * @version 1.0
     */
    public class CaptureConsoleOutput {
    
        /** Der Prozess der belegt wird */
        private static Process process;
    
        /** Startet das im Parameter args übergebene Programm samt Parameter und
         * protokolliert die Ausgabe des Programms.
         * ACHTUNG: Manche Programme schreiben ausschließlich auf den Error-Stream
         *          inStreams[1] - wie beispielsweise javac. Wenn die Ausgabe dieser
         *          Programme gesichert werden will darf das Array inStreams[] nur
         *          den Error-Stream beinhalten da sonst das Programm hängt!
         * @param   args    Die Kommandozeile getrennt in einzelne Tokens
         * @return  Der Text der vom Programm ausgegeben wurde in einem StringBuffer
         */
        public static StringBuffer startAndCapture(String[] args) {
            try {
                // Starte das Programm.
                process = Runtime.getRuntime().exec(args);
            } catch(IOException e) {
                e.printStackTrace();
                System.exit(1);
            }
    
             // Hole die Streams, die vom Prozess neu erzeugt wurden.
             InputStream[] inStreams = new InputStream[] {process.getInputStream(), process.getErrorStream()};
             StringBuffer buffer = new StringBuffer();
    
             char[] buff = new char[256];
             int count=0;
             for (int z=0; z<inStreams.length; z++) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(inStreams[z]));
                try {
                    while(-1 != (count = reader.read(buff, 0, buff.length))) {
                        buffer.append(String.valueOf(buff, 0, count));
                    }
                 } catch(IOException e) {
                    JOptionPane.showMessageDialog(null, "Error reading from BufferedReader: " + e);
                    System.exit(1);
                 }
             }
    
             process.destroy();
             try {
                process.waitFor(); // macht unter Win98 Probleme ...
             } catch(InterruptedException e) {
                e.printStackTrace();
             }
    
             return buffer;
         }
    
         /** Demo für CaptureConsoleOutput */
         public static void main (String args[]) {
            String[] prog = new String[] {"ping", "localhost"};
    
            StringBuffer buffer = CaptureConsoleOutput.startAndCapture(prog);
            String cmdLine = new String();
            for (int i=0; i<prog.length; i++) {
                cmdLine += prog[ i ];
            }
            JFrame frame = new JFrame("Captured output of \""+cmdLine+"\"");
            frame.setSize(300, 200);
            JTextArea area = new JTextArea(buffer.toString());
            JScrollPane sp = new JScrollPane(area);
            frame.getContentPane().setLayout(new BorderLayout());
            frame.getContentPane().add(sp);
            frame.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent evt) {
                    System.exit(0);
                }
            });
            frame.setVisible(true);
         }
    }
    

    Wie im Kommentar zu startAndCapture(...) schon steht funktioniert diese Klasse mit den meisten Programmen gut zusammen. Lediglich bei Programmen, die ausschließlich auf den ErrorStream schreiben (dazu zählt auch javac macht es Probleme, da bei diesen Programmen der normale OutputStream inStreams[0] leer bleibt und ergo die while-Schleife hängt - Vielleicht kann ja jemand hierfür eine Lösung finden; ich wollte nicht weiter forschen [img]images/smiles/icon_smile.gif[/img]

    In diesem Falle einfach das Array inStreams[] nur mit dem ErrorStream (***process.getErrorStream()***) füllen.

    Happy Capturing ...


Anmelden zum Antworten