From 33613a85afc4b1481367fbe92a17ee59c240250b Mon Sep 17 00:00:00 2001 From: Sven Eisenhauer Date: Fri, 10 Nov 2023 15:11:48 +0100 Subject: add new repo --- .../hjp5/html/k100123.html | 781 +++++++++++++++++++++ 1 file changed, 781 insertions(+) create mode 100644 Master/Reference Architectures and Patterns/hjp5/html/k100123.html (limited to 'Master/Reference Architectures and Patterns/hjp5/html/k100123.html') diff --git a/Master/Reference Architectures and Patterns/hjp5/html/k100123.html b/Master/Reference Architectures and Patterns/hjp5/html/k100123.html new file mode 100644 index 0000000..3892152 --- /dev/null +++ b/Master/Reference Architectures and Patterns/hjp5/html/k100123.html @@ -0,0 +1,781 @@ + + + +Handbuch der Java-Programmierung, 5. Auflage + + + + + + + + + +
 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

+ +

+Basis aller sequenziellen Eingaben ist die abstrakte Klasse Reader, +die eine Schnittstelle für stream-basierte Eingaben zur Verfügung +stellt: +

+ + + + + +
+ +
+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
+ +

+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. + + + + +

18.3.2 Auswahl des Eingabegerätes

+ +

+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. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
KlasseBedeutung
InputStreamReaderBasisklasse für alle Reader, die einen +Byte-Stream in einen Character-Stream umwandeln.
FileReaderKonkrete Ableitung von InputStreamReader +zum Einlesen aus einer Datei.
FilterReaderAbstrakte Basisklasse für die Konstruktion +von Eingabefiltern.
PushbackReaderEingabefilter mit der Möglichkeit, +Zeichen zurückzugeben.
BufferedReaderReader zur Eingabepufferung und zum Lesen +von kompletten Zeilen.
LineNumberReaderAbleitung aus BufferedReader +mit der Fähigkeit, Zeilen zu zählen.
StringReaderReader zum Einlesen von Zeichen aus einem +String. +
CharArrayReaderReader zum Einlesen von Zeichen aus einem +Zeichen-Array.
PipedReaderReader zum Einlesen von Zeichen aus einem +PipedWriter. +
+

+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.

+ + + + +
 Hinweis 
+
+ + + + +

InputStreamReader und FileReader

+ +

+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: +

+ + + + + +
+ +
+public FileReader(String fileName)
+  throws FileNotFoundException
+
+public FileReader(File file)
+  throws FileNotFoundException
+
+public FileReader(FileDescriptor fd)
+
+
+
+java.io.FileReader
+ +

+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: + + +

+ + + + + +
+ +
+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
+ +Listing 18.6: Anwendung der Klasse FileReader

+ +

+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
+
+ + + + + +

StringReader und CharArrayReader

+ +

+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
+ +Listing 18.7: Verwendung der Klasse StringReader

+ +

+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:
+
+ + + + + +

18.3.3 Schachteln von Eingabe-Streams +

+ +

+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. + + + + +

BufferedReader

+ +

+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
+ +Listing 18.8: Eingabepufferung beim Lesen aus Dateien

+ +

+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. + + + + +

LineNumberReader

+ +

+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
+ +Listing 18.9: Die Klasse LineNumberReader

+ +

+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
+
+ + + + + +

FilterReader und PushbackReader

+ +

+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 +
+ + + -- cgit v1.2.3