1. InputStreamReader
Klasse
Eine weitere interessante Funktion von Streams besteht darin, dass Sie mehrere Streams zu Ketten zusammenfassen können . Ein Stream kann Daten nicht nur aus seiner internen Datenquelle lesen, sondern auch aus einem anderen Stream .
Dies ist ein sehr leistungsfähiger Mechanismus in Java, der es ermöglicht, komplexe Datenleseszenarien zu erstellen, indem ein Stream mit einem anderen verbunden wird. Ein solches Schema sieht folgendermaßen aus:
Wenn ein Programm Daten aus einem Datenstrom liest, liest der Datenstrom wiederum die Daten aus seiner Datenquelle, bei der es sich beispielsweise um einen anderen Datenstrom oder eine Datei handelt.
Darüber hinaus liest jeder Datenstrom nicht nur Daten ein und gibt sie aus, sondern kann diese auch transformieren oder verschiedene Operationen daran ausführen. Ein gutes Beispiel für einen solchen „Zwischenstrom“ ist die InputStreamReader
Klasse.
Wir kennen bereits eine Klasse namens FileReader
– es ist eine Reader
, die Daten aus einer Datei liest. Und woher InputStreamReader
kommen die Daten? Das ist richtig – von einem InputStream
.
Wenn Sie ein Objekt erstellen , müssen Sie ein Objekt oder eine seiner Nachkommenklassen InputStreamReader
übergeben . InputStream
Beispiel:
String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);
Die InputStreamReader
Klasse verfügt über alle Methoden der Reader
Klasse und sie funktionieren auf genau die gleiche Weise.
Der Hauptunterschied zwischen der InputStreamReader
Klasse und beispielsweise FileReader
besteht darin, woher sie Daten lesen. FileReader
liest Daten aus einer Datei (duh – deshalb heißt es FileReader
), liest aber InputStreamReader
Daten aus einer InputStream
.
FileReader
Wenn Sie mit der Methode ein Zeichen aus einem Objekt lesen read()
, liest diese wiederum zwei Bytes aus der Datei auf der Festplatte und gibt sie als zurück chars
.
Wenn Sie mit der Methode ein Zeichen aus einem InputStreamReader
Objekt lesen read()
, liest diese wiederum zwei Bytes aus dem FileInputStream
an sie übergebenen Objekt, das wiederum Daten aus der Datei liest. Das Ergebnis ist eine Kette von Methodenaufrufen read()
.
2. BufferedReader
Klasse
Eine weitere interessante Klasse, die Sie wahrscheinlich häufig verwenden werden, ist BufferedReader
. Dies ist auch ein „Zwischenstream“, der Daten aus einem anderen Stream liest.
Wie der Name schon sagt, BufferedReader
ist die Klasse eine Unterklasse von Reader
und ermöglicht das Lesen von Zeichen . Am interessantesten ist jedoch, dass Sie ihm auch eine Datenquelle in Form eines Streams übergeben müssen, aus dem Zeichen gelesen werden können , dh eines Streams, der die Reader
Klasse erbt.
Was ist der Punkt? Im Gegensatz zu wandelt InputStreamReader
die BufferedReader
Klasse keine Bytes in Zeichen um: Sie konvertiert überhaupt nichts. Stattdessen werden Daten gepuffert .
Wenn ein Programm ein einzelnes Zeichen von einem BufferedReader
Objekt liest, liest das Objekt gleichzeitig eine große Anzahl von Zeichen aus seinem Quellstream. Und speichert sie intern.
Wenn das nächste Zeichen aus dem Objekt gelesen wird BufferedReader
, greift es einfach das nächste Zeichen aus seinem internen Pufferarray und gibt es zurück, ohne auf die Datenquelle zuzugreifen. Erst wenn alle Zeichen im Puffer aufgebraucht sind, wird ein weiteres großes Zeichenarray eingelesen.
Die BufferedReader
Klasse verfügt außerdem über eine sehr nützliche Methode – String readLine()
, mit der Sie ganze Datenstrings auf einmal aus dem Quellstream lesen können. Mit dieser Methode können Sie beispielsweise eine Datei lesen und deren Inhalt Zeile für Zeile auf dem Bildschirm anzeigen. Beispiel:
Wir haben speziell einen kompakten Code geschrieben, um zu veranschaulichen, wie praktisch dies sein kann. Dieser Code könnte auch etwas detaillierter geschrieben werden.
|
Erstellen Sie ein FileReader Objekt. Die Datenquelle ist eine Datei. Erstellen Sie ein BufferedReader Objekt. Die Datenquelle ist eine FileReader . Solange sich noch Daten im Lesegerät befinden. Eine Zeile lesen. Zeile anzeigen |
Wenn Sie mehrere Streams verketten, close()
muss die Methode nur für einen von ihnen aufgerufen werden. Dieser Stream ruft die Methode für seine Datenquelle usw. auf, bis sie close()
für den endgültigen Datenstream aufgerufen wird.
3. Lesen von der Konsole
Und noch eine interessante Tatsache: Die Scanner
Klasse ist nichts anderes als ein Zwischeneingabestrom, der Daten aus liest System.in
, was auch ein Datenstrom ist.
Es gibt zwei Möglichkeiten, eine Zeile von der Konsole zu lesen:
Scannerklasse | BufferedReader- und BufferedWriter-Klassen |
---|---|
|
|
Unser Freund ist nichts anderes als eine statische Variable der Klasse. Es ist ein , dessen Name ist .System.in
in
System
InputStream
in
Sie haben also fast von Beginn Ihres Java-Studiums auf CodeGym an mit Datenströmen gearbeitet und daraus Ketten aufgebaut. Aber jetzt wirst du es bewusster tun.
GO TO FULL VERSION