1. InputStreamReaderKlasse

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:

InputStreamReader-Klasse

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

Wir kennen bereits eine Klasse namens FileReader– es ist eine Reader, die Daten aus einer Datei liest. Und woher InputStreamReaderkommen die Daten? Das ist richtig – von einem InputStream.

Wenn Sie ein Objekt erstellen , müssen Sie ein Objekt oder eine seiner Nachkommenklassen InputStreamReaderübergeben . InputStreamBeispiel:

String src = "c:\\projects\\log.txt";
FileInputStream input = new FileInputStream(src);
InputStreamReader reader = new InputStreamReader(input);

Die InputStreamReaderKlasse verfügt über alle Methoden der ReaderKlasse und sie funktionieren auf genau die gleiche Weise.

Der Hauptunterschied zwischen der InputStreamReaderKlasse und beispielsweise FileReaderbesteht darin, woher sie Daten lesen. FileReaderliest Daten aus einer Datei (duh – deshalb heißt es FileReader), liest aber InputStreamReaderDaten aus einer InputStream.

FileReaderWenn 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 InputStreamReaderObjekt lesen read(), liest diese wiederum zwei Bytes aus dem FileInputStreaman sie übergebenen Objekt, das wiederum Daten aus der Datei liest. Das Ergebnis ist eine Kette von Methodenaufrufen read().


2. BufferedReaderKlasse

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, BufferedReaderist die Klasse eine Unterklasse von Readerund 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 ReaderKlasse erbt.

Was ist der Punkt? Im Gegensatz zu wandelt InputStreamReaderdie BufferedReaderKlasse keine Bytes in Zeichen um: Sie konvertiert überhaupt nichts. Stattdessen werden Daten gepuffert .

Wenn ein Programm ein einzelnes Zeichen von einem BufferedReaderObjekt 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 BufferedReaderKlasse 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.

String src = "c:\\projects\\log.txt";

try(FileReader in = new FileReader(src);
BufferedReader reader = new BufferedReader(in))
{
   while (reader.ready())
   {
      String line = reader.readLine();
      System.out.println(line);
   }
}
Erstellen Sie ein FileReaderObjekt. Die Datenquelle ist eine Datei.
Erstellen Sie ein BufferedReaderObjekt. Die Datenquelle ist eine FileReader.
Solange sich noch Daten im Lesegerät befinden.
Eine Zeile lesen.
Zeile anzeigen
Ein wichtiger Punkt:

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 ScannerKlasse 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
InputStream stream = System.in;
Scanner console = new Scanner(stream);
String line = console.nextLine();
InputStream stream = System.in;
InputStreamReader reader = new InputStreamReader(stream);
BufferedReader buff = new BufferedReader(reader);
String line = buff.readLine();

Unser Freund ist nichts anderes als eine statische Variable der Klasse. Es ist ein , dessen Name ist .System.ininSystemInputStreamin

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.