25.6 Die Klasse PrintWriter
 
Ausgabe in Datei Das Schreiben in eine Datei können wir uns in drei Schritten aufgeteilt vorstellen:
  • Erzeuge eine FileOutputStream-Objekt und übergib ihm dabei den Namen der Datei als ein String-Objekt.
  • Erzeuge ein PrintWriter-Objekt und übergib ihm dabei das soeben erzeugte FileOutputStream-Objekt.
  • Benutze die Objekt-Methode println(String text) der Klasse PrintWriter, um eine Zeichenkette 'auf einen Rutsch' in die Datei zu schreiben. und schließe das PrintWriter-Objekt.

der letzte Schritt etwas genauer: println(String text) übergibt, ohne dass wir etwas davon merken - und so soll es auch sein - eine ganze Zeichenkette an das FileOutputStream-Objekt, das die eigentliche Arbeit leistet, nämlich das Einspeisen der Daten in die Ausgabe-Pipeline. Das Auslesen aus dieser Ausgabe-Pipeline und Schreiben in die Datei schließlich, leistet das Betriebssystem.

  ...
String dateiName = "Test.txt";
FileOutputStream speicherStrom =
                          new FileOutputStream(dateiName);
PrintWriter schreibeStrom = new PrintWriter(speicherStrom);
schreibeStrom.println(text); 
schreibeStrom.close();
...                             

 
Ausgabe auf den Bildschirm Objekte der Klasse PrintWriter kann man z.B. auch dazu benutzen, Daten an einen Bildschirm zu senden: Dazu übergeben wird dem PrintWriter-Objekt an Stelle eines FileWriter-Objektes den Standard-Ausgabestrom, das Klassenobjekt System.out. Wir gehen jetzt also so vor:
  • Erzeuge ein PrintWriter-Objekt und übergebe ihm dabei den Standard-Ausgabestrom System.out.
  • Benutze die Objekt-Methode println(String text) der Klasse PrintWriter, um eine Zeichenkette 'auf einen Rutsch' auf den Bildschirm zu schreiben. und schließe das PrintWriter-Objekt.

Was wir oben über die Methode println(String text) aus der Klasse PrintWriter bei der Ausgabe in eine Datei gesagt haben, gilt natürlich auch hier.

   
Download:
Ausgaben. java
import java.io.*;

public class Ausgaben {

  public static void main (String[] args) throws IOException{
    String text = "Java ist toll!";
    String dateiName = "Test.txt";
    FileOutputStream speicherStrom = 
                               new FileOutputStream(dateiName);

    PrintWriter schreibeStrom1 = 
                               new PrintWriter(speicherStrom);
    schreibeStrom1.println(text);
    schreibeStrom1.close();

    PrintWriter schreibeStrom2 = new PrintWriter(System.out);
    schreibeStrom2.println(text);
    schreibeStrom2.close();
  }
}
  Auf dem Bildschirm erscheint nach einer kleinen Verzögerung der Text "Java ist toll". Die Verzögerung stammt daher, dass die Datei 'Test.txt' erzeugt wurde, wie ein Blick in das Verzeichnis bestätigt.
 
Ergänzende Erklärungen für die, die noch mehr wissen wollen Beim Erzeugen der PrintWriter-Objekte wird einmal ein FileOutputStream-Objekt (speicherStrom) und zum anderen ein PrintStream-Objekt (System.out) dem Konstruktor übergeben. Handelt es sich dabei um zwei verschiedene Konstruktoren, die sich also in der Signatur unterscheiden? Wir werden sehen, dass es sich um ein und den selben Konstruktor handelt, nämlich:
 

 


Vergleichen wir die beiden Klassen FileOutputStream und PrintStream. Die Java-Spezifikation (API) zeigt in welchen Paketen sich die Klassen befinden und, hier noch wichtiger, von welchen Klassen sie erben.

Wir sehen, dass beide Klassen sich von der Klasse OutputStream ableiten. Das bedeutet, dass ein FileOutputStream-Objekt auch ein OutputStream-Objekt ist und, dass ein PrintStream-Objekt ein FilterOutputStream-Objekt und weiter auch ein OutputStream-Objekt ist.

In
 

 

PrintWriter schreibeStrom1 =
                   new
PrintWriter(einFileOutputStream);

PrintWriter schreibeStrom2 =
                   new
PrintWriter(einPrintStream);

werden also beides mal die gleichen Konstruktoren benutzt.

Die Verpackung der FileOutputStream- und PrintStream-Objekte, oder wie wir lieber sagen, die Kapselung der beiden Objekte in ein PrintWriter-Objekt erlaubt uns den komfortablen Umgang mit den Strömen. Grafisch lässt sich das so darstellen:
 

Ein Konzept wird sichtbar

Die roten Pfeile sollen darauf hinweisen, dass es das Betriebssystem ist, das die Daten der Pipeline entnimmt. Die hellrot dargestellten Pipelines darf man sich als Schnittstellen zwischen Betriebssystem und Java sehen, Das Einspeisen auf der rechten Seite ist die Aufgabe eines Javaprogramms. Das Zwischenschalten der PrintWriter-Objekte, das wir durch die Übergabe der OutputStream-Objekte erreichen, gestattet uns eine Vereinheitlichung der Aushgabe, weil wir nur noch Methoden der Klasse PrintWriter benutzen müssen. Die hier duetlich gewordene Strategie legt nahe, dass man vielleicht noch andere OutPutStream-Objekte auf die gleiche Weise in das Konzept einbinden kann. Dies ist tatsächlich der Fall, wie wir in Kapitel 23 noch sehen werden.

Vorher wollen wir uns eine kleine Variante in der Behandlung der Ausgabeströme ansehen und in 22.7 noch lernen, wie wir Eingabeströme vereinheitlichen und wesentlich komfortabler gestalten können.
 

Erst die Variante Es gibt 4 Konstruktoren der Klasse PrintWriter. Ein Blick in die API zeigt sie uns auf.
 
  Wir können diese 4 Konstruktoren in zwei Gruppen einteilen. In der einene Gruppe werden Writer-Objekte, in der anderen OutputStreram-Objekte übergeben. In jeder Gruppe gibt es wieder eine Unterscheidung in der Anzahl der übergebenen Parameter. Neben den Konstruktoren mit einem Parameter, gibt es noch die mit einem weiteren. Der zweite Parameter ist vom Typ boolean; ist dessen Wert true, wird  die Pipeline automatisch geleert.

Die Spezifikation der Klasse FileWriter, zeigt dass sie sich von der Klasse Writer ableitet. Das gibt uns die Möglichkeit in unserem Programm die Zeile:

FileOutputStream speicherStrom =
                    new
FileOutputStream(dateiName);
durch

FileWriter speicherStrom =
                    new
FileWriter(dateiName);

zu ersetzen. Man beachte dass in den Zeilen

PrintWriter schreibeStrom1 =
               new
PrintWriter(speicherStrom);

und

PrintWriter schreibeStrom2 =
               new
PrintWriter(System.out);

jetzt zwei unterschiedliche Konstruktoren benutzt werden, während die absolut gleichen Zeilen im ursprünglichen Programm gleichen Konstruktoren benutzt. 

   
zu 25.7 Die Klasse BufferedReader
zur Startseite www.pohlig.de  (C) MPohlig 2005