From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001
From: Sven Eisenhauer
+Basis aller sequenziellen Eingaben ist die abstrakte Klasse Reader,
+die eine Schnittstelle für stream-basierte Eingaben zur Verfügung
+stellt:
+
+
+Analog zu den write-Methoden
+von Writer
+stellt die Klasse Reader
+eine Reihe von read-Methoden
+zum Lesen von Daten zur Verfügung. Die parameterlose Variante
+liest das nächste Zeichen aus dem Eingabestrom und liefert es
+als int,
+dessen Wert im Bereich von 0 bis 65535 liegt. Ein Rückgabewert
+von -1 zeigt das Ende des Eingabestroms an. Die beiden anderen Varianten
+von read
+übertragen eine Reihe von Zeichen in das als Parameter übergebene
+Array und liefern die Anzahl der tatsächlich gelesenen Zeichen
+als Rückgabewert. Auch hier wird -1 zurückgegeben, wenn
+das Ende des Streams erreicht ist.
+
+
+Die Methode ready
+liefert true,
+falls der nächste Aufruf von read
+erfolgen kann, ohne dass die Eingabe blockt, und close
+schließt den Eingabestrom. Mit Hilfe der Methoden mark
+und reset
+gibt es die Möglichkeit, eine bestimmte Position innerhalb des
+Eingabe-Streams zu markieren und zu einem späteren Zeitpunkt
+wieder anzuspringen. Zuvor muss allerdings durch einen Aufruf von
+markSupported
+überprüft werden, ob das Markieren überhaupt unterstützt
+wird. Ist dies nicht der Fall, würde ein Aufruf von mark
+oder reset
+eine Ausnahme erzeugen. Die Methode mark
+merkt sich die aktuelle Leseposition und spezifiziert, wie viele Bytes
+anschließend maximal gelesen werden können, bevor die Markierung
+ungültig wird. Ein Aufruf von reset
+setzt den Lesezeiger an die markierte Stelle zurück.
+
+
+Mit der Methode skip
+ist es möglich, n Zeichen im Eingabestrom zu überspringen.
+Dabei kann es aus verschiedenen Gründen vorkommen, dass nicht
+exakt die angegebene Anzahl an Zeichen übersprungen wird (beispielsweise,
+wenn nicht mehr genügend Zeichen vorhanden sind). Der Rückgabewert
+von skip
+gibt die tatsächliche Anzahl an.
+
+
+
+
+
+Analog zur Klasse Writer
+dient auch bei der Klasse Reader
+die erste Ebene abgeleiteter Klassen vorwiegend dazu, die Art des
+Datenlieferanten zu bestimmen. Tabelle 18.2
+gibt eine Übersicht der aus Reader
+abgeleiteten Klassen.
+
+
+
+Tabelle 18.2: Aus Reader abgeleitete Klassen
+In den folgenden Unterabschnitten werden die Klassen InputStreamReader,
+FileReader,
+StringReader
+und CharArrayReader
+erläutert. FilterReader,
+PushbackReader,
+BufferedReader
+und LineNumberReader
+werden in Abschnitt 18.3.3
+behandelt.
+
+
+Die Klasse PipedReader
+soll hier nicht erläutert werden. In Abschnitt 22.4.4
+findet sich jedoch ein Beispiel zur Anwendung der Klassen PipedInputStream
+und PipedOutputStream,
+das auf PipedReader
+und PipedWriter
+übertragbar ist.
+Die Klasse InputStreamReader
+ist die Basisklasse für alle Reader, die eine Konvertierung zwischen
+Byte- und Character-Streams vornehmen. Sie enthält ein Objekt
+des Typs ByteToCharConverter
+(aus dem undokumentierten Paket sun.io),
+das die Konvertierung der Eingabezeichen bei allen lesenden Zugriffen
+vornimmt. Als übergeordnete Basisklasse ist InputStreamReader
+für uns allerdings nicht so interessant wie die daraus abgeleitete
+Klasse FileReader,
+die die Eingabe aus einer Datei ermöglicht. Sie implementiert
+die abstrakten Eigenschaften von Reader
+und bietet zusätzliche Konstruktoren, die es erlauben, eine Datei
+zu öffnen:
+
+
+Bei der Übergabe der Zeichenkette fileName
+wird die Datei mit dem angegebenen Namen zum Lesen geöffnet.
+Falls sie nicht vorhanden ist, löst der Konstruktor eine Ausnahme
+des Typs FileNotFoundException
+aus. Die beiden anderen Konstruktoren erwarten ein File-Objekt,
+das eine zu öffnende Datei spezifiziert, oder ein FileDescriptor-Objekt,
+das eine bereits geöffnete Datei angibt.
+
+
+Das folgende Beispiel demonstriert die Anwendung der Klasse FileReader.
+Das Programm liest die Datei config.sys
+und gibt ihren Inhalt auf dem Bildschirm aus:
+
+
+
+
+
+
+ Titel
+ Inhalt
+ Suchen
+ Index
+ DOC
+ Handbuch der Java-Programmierung, 5. Auflage
+
+ <<
+ <
+ >
+ >>
+ API
+ Kapitel 18 - Character-Streams
+
+
+
+
+
+18.3 Eingabe-Streams
+
+
+
+
+
+
+
+
+18.3.1 Die abstrakte Klasse Reader
+
+
+
+
+
+
+
+
+
+
+public Reader()
+
+public void close()
+public void mark(int readAheadlimit)
+public boolean markSupported()
+
+public int read()
+public int read(char[] cbuf)
+public int read(char[] cbuf, int off, int len)
+
+public long skip(long n)
+public boolean ready()
+public void reset()
+
+
+
+java.io.Reader
+18.3.2 Auswahl des Eingabegerätes
+
+
+
+
+
+
+Klasse
+Bedeutung
+
+InputStreamReader
+Basisklasse für alle Reader, die einen
+Byte-Stream in einen Character-Stream umwandeln.
+
+FileReader
+Konkrete Ableitung von InputStreamReader
+zum Einlesen aus einer Datei.
+
+FilterReader
+Abstrakte Basisklasse für die Konstruktion
+von Eingabefiltern.
+
+PushbackReader
+Eingabefilter mit der Möglichkeit,
+Zeichen zurückzugeben.
+
+BufferedReader
+Reader zur Eingabepufferung und zum Lesen
+von kompletten Zeilen.
+
+LineNumberReader
+Ableitung aus BufferedReader
+mit der Fähigkeit, Zeilen zu zählen.
+
+StringReader
+Reader zum Einlesen von Zeichen aus einem
+String.
+
+
+CharArrayReader
+Reader zum Einlesen von Zeichen aus einem
+Zeichen-Array.
+
+PipedReader
+Reader zum Einlesen von Zeichen aus einem
+PipedWriter.
+
+
+
+
+
+
+
+
+
+
+![]()
+
+
+
+![]()
+
+
+
+
+
+ Hinweis
+
+
InputStreamReader und FileReader
+
+
+
+
+
+
+
+
+
+
+public FileReader(String fileName)
+ throws FileNotFoundException
+
+public FileReader(File file)
+ throws FileNotFoundException
+
+public FileReader(FileDescriptor fd)
+
+
+
+java.io.FileReader
+
+
+
+Listing 18.6: Anwendung der Klasse FileReader
+
+
+
+
+
+001 /* Listing1806.java */
+002
+003 import java.io.*;
+004
+005 public class Listing1806
+006 {
+007 public static void main(String[] args)
+008 {
+009 FileReader f;
+010 int c;
+011
+012 try {
+013 f = new FileReader("c:\\config.sys");
+014 while ((c = f.read()) != -1) {
+015 System.out.print((char)c);
+016 }
+017 f.close();
+018 } catch (IOException e) {
+019 System.out.println("Fehler beim Lesen der Datei");
+020 }
+021 }
+022 }
+
+
+Listing1806.java
+
+Die Ausgabe des Programms ist:
+
+
+DEVICE=c:\windows\himem.sys
+DOS=HIGH,UMB
+DEVICE=c:\windows\emm386.exe noems
+SHELL=c:\command.com/e:1536/p
+FILES=101
+BUFFERS=5
+DEVICEHIGH=c:\windows\command\ansi.sys
+
+
+
+
+
+
+
+Diese beiden Klassen sind die Pendants zu StringWriter +und CharArrayWriter. +Sie erlauben das Lesen von Zeichen aus einem String +bzw. einem Zeichen-Array. Die Schnittstelle der beiden Klassen ist +identisch und unterscheidet sich von der Basisklasse Reader +nur durch die geänderten Konstruktoren: +
+
+
++public StringReader(String s) ++ + |
++java.io.StringReader | +
+
+
++public CharArrayReader(char[] buf) + +public CharArrayReader(char[] buf, int offset, int length) ++ + |
++java.io.CharArrayReader | +
+Das folgende Programm zeigt die Verwendung der Klasse StringReader +am Beispiel eines Programms, das einen Reader +konstruiert, der den Satz liest, der hier an dieser Stelle steht: + + +
+
+
+
+001 /* Listing1807.java */
+002
+003 import java.io.*;
+004
+005 public class Listing1807
+006 {
+007 public static void main(String[] args)
+008 {
+009 Reader f;
+010 int c;
+011 String s;
+012
+013 s = "Das folgende Programm zeigt die Verwendung\r\n";
+014 s += "der Klasse StringReader am Beispiel eines\r\n";
+015 s += "Programms, das einen Reader konstruiert, der\r\n";
+016 s += "den Satz liest, der hier an dieser Stelle steht:\r\n";
+017 try {
+018 f = new StringReader(s);
+019 while ((c = f.read()) != -1) {
+020 System.out.print((char)c);
+021 }
+022 f.close();
+023 } catch (IOException e) {
+024 System.out.println("Fehler beim Lesen des Strings");
+025 }
+026 }
+027 }
+
+ |
++Listing1807.java | +
+Die Ausgabe des Programms ist:
+
+
+Das folgende Programm zeigt die Verwendung
+der Klasse StringReader am Beispiel eines
+Programms, das einen Reader konstruiert, der
+den Satz liest, der hier an dieser Stelle steht:
+
+
+
+
+
+
+
+Das Konzept der geschachtelten Streams funktioniert bei der sequenziellen +Eingabe genauso wie bei der Ausgabe. Mit den Klassen BufferedReader, +LineNumberReader, +FilterReader +und PushbackReader +stehen Klassen zur Verfügung, die im Konstruktor die Übergabe +eines weiteren Readers erwarten und die Leseoperationen vor Ausführung +der Filterfunktion an diesen Reader +weiterleiten. + + + + +
+Dieser Filter dient zur Pufferung von Eingaben und kann verwendet +werden, um die Performance beim Lesen von externen Dateien zu erhöhen. +Da nicht jedes Byte einzeln gelesen wird, verringert sich die Anzahl +der Zugriffe auf den externen Datenträger, und die Lesegeschwindigkeit +erhöht sich. Zusätzlich stellt BufferedReader +die Methode readLine +zur Verfügung, die eine komplette Textzeile liest und als String +an den Aufrufer zurückgibt: +
+
+
++public String readLine() + throws IOException ++ + |
++java.io.BufferedReader | +
+Eine Textzeile wird dabei durch die Zeichen '\n' +oder '\r' oder durch die Folge +"\r\n" begrenzt. Der Rückgabewert +von readLine +ist ein String, +der den Zeileninhalt ohne Begrenzungszeichen enthält bzw. null, +falls das Ende des Streams erreicht ist. BufferedReader +besitzt zwei Konstruktoren: +
+
+
++public BufferedReader(Reader in) + +public BufferedReader(Reader in, int sz) ++ + |
++java.io.BufferedReader | +
+Der erste Parameter in ist das +Reader-Objekt, +auf dem der BufferedReader +aufgesetzt werden soll. Der optionale zweite Parameter sz +gibt die Größe des internen Puffers an. Fehlt er, so wird +eine für die meisten Situationen angemessene Standardeinstellung +verwendet. + +
+Das folgende Beispiel demonstriert den Einsatz der Eingabepufferung +durch die Erweiterung von Listing 18.6. +Auch hier wird die Datei config.sys eingelesen +und auf dem Bildschirm ausgegeben. Durch den Einsatz der Klasse BufferedReader +versucht das Programm, die Perfomance beim Lesen der Datei zu erhöhen: + + +
+
+
+
+001 /* Listing1808.java */
+002
+003 import java.io.*;
+004
+005 public class Listing1808
+006 {
+007 public static void main(String[] args)
+008 {
+009 BufferedReader f;
+010 String line;
+011
+012 try {
+013 f = new BufferedReader(
+014 new FileReader("c:\\config.sys"));
+015 while ((line = f.readLine()) != null) {
+016 System.out.println(line);
+017 }
+018 f.close();
+019 } catch (IOException e) {
+020 System.out.println("Fehler beim Lesen der Datei");
+021 }
+022 }
+023 }
+
+ |
++Listing1808.java | +
+Zusätzlich wird die Eingabe nicht zeichen-, sondern mit Hilfe +von readLine +zeilenweise gelesen, was die Performance weiter erhöht. Die Ausgabe +des Programms ist mit der von Listing 18.6 +identisch. + + + + +
+Diese Klasse ist eine Ableitung von BufferedReader, +die um die Fähigkeit erweitert wurde, die Anzahl der Eingabezeilen +beim Einlesen zu zählen. Die Schnittstelle entspricht dabei exakt +der von BufferedReader, +erweitert um die Methoden getLineNumber +und setLineNumber: +
+
+
++public int getLineNumber() + +public void setLineNumber(int lineNumber) ++ + |
++java.io.LineNumberReader | +
+Mit getLineNumber +wird der aktuelle Stand des Zeilenzählers abgefragt, mit setLineNumber +kann er sogar verändert werden. + +
+Das folgende Beispiel erweitert unsere bisherigen Programme zur Ausgabe +der Datei config.sys in der Weise, dass +nun jede einzelne Zeile mit vorangestellter Zeilennummer angezeigt +wird. Dazu wird der BufferedReader +durch einen LineNumberReader +ersetzt und vor der Ausgabe jeder einzelnen Zeile zunächst die +korrespondierende Zeilennummer ausgegeben: + + +
+
+
+
+001 /* Listing1809.java */
+002
+003 import java.io.*;
+004
+005 public class Listing1809
+006 {
+007 public static void main(String[] args)
+008 {
+009 LineNumberReader f;
+010 String line;
+011
+012 try {
+013 f = new LineNumberReader(
+014 new FileReader("c:\\config.sys"));
+015 while ((line = f.readLine()) != null) {
+016 System.out.print(f.getLineNumber() + ": ");
+017 System.out.println(line);
+018 }
+019 f.close();
+020 } catch (IOException e) {
+021 System.out.println("Fehler beim Lesen der Datei");
+022 }
+023 }
+024 }
+
+ |
++Listing1809.java | +
+Die Ausgabe des Programms ist nun:
+
+
+1: DEVICE=c:\windows\himem.sys
+2: DOS=HIGH,UMB
+3: DEVICE=c:\windows\emm386.exe noems
+4: SHELL=c:\command.com/e:1536/p
+5: FILES=101
+6: BUFFERS=5
+7: DEVICEHIGH=c:\windows\command\ansi.sys
+
+
+
+
+
+
+
+Das Schachteln von Eingabestreams funktioniert analog zum Schachteln +von Ausgabestreams. Auch hier existiert eine abstrakte Basisklasse +FilterReader, +die den eigentlichen Reader +im Konstruktor übergeben bekommt und als Membervariable speichert. +Bei der Konstruktion eigener Eingabefilter kann analog zur Konstruktion +von Ausgabefiltern vorgegangen werden. + +
+Das JDK 1.1 enthält einen vordefinierten Eingabefilter PushbackReader, +der aus FilterReader +abgeleitet wurde. Ein PushbackReader +erweitert die Klasse FilterReader +um einen ein Byte großen Pushbackbuffer. Dieser erlaubt +einer Anwendung, das zuletzt gelesene Zeichen wieder in den Eingabestrom +zurückzuschieben. Der nächste Lesezugriff liest dann nicht +das folgende Zeichen im Eingabestrom, sondern das gerade zurückgegebene +Zeichen. Wahlweise kann beim Aufruf des Konstruktors die Größe +des Pushbackbuffers angegeben werden: +
+
+
++public PushbackReader(Reader in) + +public PushbackReader(Reader in, int size) ++ + |
++java.io.PushbackReader | +
+Ein PushbackReader +kann beispielsweise angewendet werden, wenn eine Methode das nächste +Eingabezeichen kennen muss, um zu entscheiden, welche Aktion als nächstes +auszuführen ist. Falls die Methode selbst nicht für die +Behandlung des Eingabezeichens zuständig ist, kann sie das Zeichen +an den Eingabestrom zurückgeben, und eine andere Methode kann +mit der Bearbeitung beauftragt werden. Derartige Techniken finden +beispielsweise in Werkzeugen zur lexikalischen Analyse Anwendung, +wie sie im Compilerbau verwendet werden. + +
+Die Rückgabe eines Zeichens wird mit Hilfe der Methode unread +durchgeführt. Diese steht in verschiedenen Varianten zur Verfügung +und kann zur Rückgabe eines einzelnen Zeichens oder mehrerer +Zeichen verwendet werden: +
+
+
++public void unread(int c) + throws IOException + +public void unread(char[] cbuf, int off, int len) + throws IOException + +public void unread(char[] cbuf) + throws IOException ++ + |
++java.io.PushbackReader | +
+Hierbei muss das oder die zurückzugebenden Zeichen als Parameter +unread +übergeben werden. +
| Titel + | Inhalt + | Suchen + | Index + | DOC + | Handbuch der Java-Programmierung, 5. Auflage, Addison +Wesley, Version 5.0.1 + |
| << + | < + | > + | >> + | API + | © 1998, 2007 Guido Krüger & Thomas +Stark, http://www.javabuch.de + |