Einleitung
In Java-Anwendungen kann es nötig sein, die Konsolenausgabe (System.out
) oder die Fehlerausgabe (System.err
) mitzuschneiden. Die Gründe dafür sind vielfältig:
- Unit-Tests: Manche Tests prüfen, ob bestimmte Texte in der Standardausgabe erscheinen.
- Debugging und Logging: Falls eine genutzte Bibliothek kein Logging-Framework unterstützt und nur
System.out
oderSystem.err
verwendet, kann man die Ausgabe umleiten. - Speicherung und Analyse: Um die Konsolenausgabe später weiterzuverarbeiten oder zu protokollieren.
Vorgehen
In Java kann die Standardausgabe und Standardfehlerausgabe durch Umleiten der Streams System.out
und System.err
auf eigene Streams mitgeschnitten werden.
1. Nutzung von ByteArrayOutputStream
Ein einfacher Ansatz ist, die Standardstreams auf einen ByteArrayOutputStream
umzuleiten:
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
public class StreamRedirectExample {
public static void main(String[] args) {
// Original-Streams speichern
PrintStream originalOut = System.out;
PrintStream originalErr = System.err;
// Neue Streams erzeugen
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
ByteArrayOutputStream errContent = new ByteArrayOutputStream();
System.setOut(new PrintStream(outContent));
System.setErr(new PrintStream(errContent));
// Test-Ausgaben
System.out.println("Dies ist eine normale Ausgabe.");
System.err.println("Dies ist eine Fehlerausgabe.");
// Zurücksetzen der Streams
System.setOut(originalOut);
System.setErr(originalErr);
// Ergebnisse anzeigen
System.out.println("Mitgeschnittene Ausgabe: " + outContent.toString());
System.out.println("Mitgeschnittene Fehlerausgabe: " + errContent.toString());
}
}
Code-Sprache: JavaScript (javascript)
2. Nutzung eines eigenen Output-Streams
Ein anderer Ansatz ist, einen eigenen OutputStream
zu erstellen, der die Daten an mehrere Ziele weiterleitet:
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
public class TeeOutputStream extends OutputStream {
private final OutputStream out1;
private final OutputStream out2;
public TeeOutputStream(OutputStream out1, OutputStream out2) {
this.out1 = out1;
this.out2 = out2;
}
@Override
public void write(int b) throws IOException {
out1.write(b);
out2.write(b);
}
@Override
public void flush() throws IOException {
out1.flush();
out2.flush();
}
@Override
public void close() throws IOException {
out1.close();
out2.close();
}
public static void main(String[] args) {
PrintStream originalOut = System.out;
ByteArrayOutputStream outContent = new ByteArrayOutputStream();
PrintStream teeStream = new PrintStream(new TeeOutputStream(originalOut, outContent));
System.setOut(teeStream);
System.out.println("Diese Ausgabe wird sowohl in die Konsole als auch in den Stream geschrieben.");
System.setOut(originalOut);
System.out.println("Mitgeschnittene Ausgabe: " + outContent.toString());
}
}
Code-Sprache: JavaScript (javascript)
3. Nutzung eines Logging-Frameworks
Falls Logging gewünscht ist, kann System.out
mit einem Logging-Framework wie SLF4J oder Logback umgeleitet werden:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.PrintStream;
public class LogRedirectExample {
private static final Logger logger = LoggerFactory.getLogger(LogRedirectExample.class);
public static void main(String[] args) {
System.setOut(new PrintStream(System.out) {
@Override
public void println(String x) {
logger.info(x);
}
});
System.out.println("Diese Nachricht wird geloggt.");
}
}
Code-Sprache: JavaScript (javascript)
Fazit
Das Mitschneiden von System.out
und System.err
ist in Java einfach möglich. Je nach Bedarf kann man einen einfachen ByteArrayOutputStream
nutzen, eine eigene OutputStream
-Implementierung schreiben oder die Ausgabe direkt an ein Logging-Framework weiterleiten. Welcher Ansatz gewählt wird, hängt vom jeweiligen Anwendungsfall ab.