Einführung in Reader- und Writerklassen

Die Reader und Writer Klassen in Java erlauben es Zeichen-Stöme zu verwalten.

Die spezialisierten Klassen FileReader und FileWriter haben Konstruktoren in denen man als Quelle bzw. Ziel eine Datei angeben kann:

Ihre Oberklassen InputStreamReader und OutputStreamWriter haben Konstruktoren die die Konvertierung von Streams erlauben.

Hiermit kann man einen Byte-Stream (inputStream)  in einen Zeichen-Stream (Reader) verwandeln. Dies ist nützlich wenn man eine Binärdatei (Byte-Stream) in eine Datei (Zeichen-Stream) schreiben möchte.

 

Java Reader und Writer Klassen

Im folgenden Beispiel wird gezeigt wie man einen Zeichen-Stream von der Konsole lesen kann und ihn dann in eine Datei schreibt. Die Java Klasse System bietet mit dem Attribute System.in Zugriff auf einen InputStream mit Konsoleneingaben und auf Konsolenausgaben (System.out).

/*
 * Ein Beispielprogramm welches von der Konsole liest und in eine Datei schreibt
 */
package s2.io;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
/**
*
* @author s@scalingbits.com
*/
public class SchreibInDatei {
   /**
   * Hauptprogamm
   * @param args wird nicht verwendet...
   */
   public static void main(String[] args) {
      try {
         String f = "scalingbits.txt";
         File datei = new File(f);
         Reader rein = new InputStreamReader(System.in);
         Writer raus = new FileWriter(datei);
         System.out.println("Der Text der jetzt eingegeben wird, wird in " +
            "der Datei " + f + " gespeichert");
         System.out.println("Abschliessen mit Strg-Z oder Ctrl-Z");
         System.out.println("Abschliessen Auf Unix/Linux mit Ctrl-D");
         System.out.println("Abschliessen auf Mac mit IntelliJ mit Cmd-D");
         umkopieren(rein,raus);
     } catch (IOException ex) {
         System.out.println("Probleme im IO Subsystem. Scotty beam me up");
     }
   }
   /**
   * Umkopieren zwischen zwei Streams
   * @param r Eingabestream
   * @param w Ausgabestream
   * @throws IOException
   */
   public static void umkopieren(Reader r, Writer w) throws IOException{
      int c;
      while ((c= r.read()) != -1 ) {
         w.write(c);
      }
      r.close();
      w.close();
   }
}

Übung: Erweitern Sie Anwendung so, dass sie die geschriebene Datei wieder ausliest und auf der Konsole druckt. Die Methoden umkopieren() kann man wiederverwenden...

Frage: Welche Klassen brauche ich hierfür?

Sie werden doch nicht auf diesen Hyperlink klicken: github s2.io.SchreibInDateiLoesung.java

 Gepufferte Reader- und Writer Klassen

Das Lesen bzw. Schreiben einzelner Bytes oder Zeichen vom Netzwerk oder von Dateien ist oft sehr ineffizient. Zum effizienteren Behandlung größerer Datenmengen stellt Java die Klassen BufferedReader und BufferedWriter zur Verfügung. Diese Klassen speichen die Daten zwischenzeitlich in einem Puffer und Lesen bzw. Schreiben die Daten in größeren Blöcken. Diese gepufferten Klassen müssen mit den elementaren Klassen verkettet werden. Deshalb haben sie die folgenden Konstruktoren:

Sie Verfügen über zusatzliche Methoden zum gepufferten Lesen und Schreiben

 Nutzt man diese Klassen im Beispiel, gibt es eine Reihe von Veränderungen:

  • mit BufferedReader.readLine() erhält man eine Zeichenkette als Ergebnis (oder einen Nullzeiger!)
  • man sollte beim Schreiben den Zeilenimbruch selbst einfügen

Die Klasse SchreibInDateiGepuffered

/*
 * Eins Beispielprogramm welches von der Konsole liest und in eine Datei schreibt
 */
package s2.io;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

/**
*
* @author s@scalingbits.com
*/
public class SchreibInDateiGepuffered {
   /**
   * Hauptprogamm
   * @param args wird nicht verwendet...
   */
   public static void main(String[] args) {
      try {
         String f = "scalingbits.txt";
         File datei = new File(f);
         BufferedReader rein = new BufferedReader(
            new InputStreamReader(System.in));
         BufferedWriter raus = new BufferedWriter(
         new FileWriter(datei));
         System.out.println("Der Text der jetzt eingegeben wird, wird in " +
               "der Datei " + f + " gespeichert");
         System.out.println("Abschliessen mit Strg-Z oder Ctrl-Z");
         System.out.println("Abschliessen Auf Unix/Linux mit Ctrl-D");
         System.out.println("Abschliessen auf Mac mit IntelliJ mit Cmd-D");
         umkopieren(rein,raus);

         rein = new BufferedReader(
         new FileReader(f));
         raus = new BufferedWriter(
         new OutputStreamWriter(System.out));

         System.out.println("Ausgabe des in Datei " + f
            + " gespeichertem Texts");
         umkopieren(rein,raus);
      } catch (IOException ex) {
         System.out.println("Probleme im IO Subsystem. Scotty beam me up");
      }
   }
   /**
   * Umkopieren zwischen zwei Streams
   * @param r Eingabestream
   * @param w Ausgabestream
   * @throws IOException
   */
   public static void umkopieren(BufferedReader r, BufferedWriter w) throws IOException{
      String z;
      while ((z= r.readLine()) != null) {
         w.write(z);
         w.newLine();
      }
      r.close();
      w.close();
   }
}

Die Datei SchreibInDateiGepuffered in github.