1. InputStreamReaderklasse

Een ander interessant kenmerk van streams is dat je meerdere streams kunt combineren tot ketens . Een stream kan niet alleen gegevens uit zijn interne gegevensbron lezen, maar ook uit een andere stream .

Dit is een zeer krachtig mechanisme in Java, dat het mogelijk maakt om complexe scenario's voor het lezen van gegevens te creëren door de ene stroom met de andere te verbinden. Zo'n schema ziet er als volgt uit:

InputStreamReader-klasse

Wanneer een programma gegevens uit een gegevensstroom leest, leest de gegevensstroom op zijn beurt de gegevens uit zijn gegevensbron, bijvoorbeeld een andere gegevensstroom of een bestand.

Bovendien leest elke datastroom niet alleen data in en geeft deze weer uit, maar kan deze ook transformeren of er verschillende bewerkingen op uitvoeren. Een goed voorbeeld van zo'n "tussenstroom" is de InputStreamReaderklas.

We kennen al een klasse genaamd FileReader— het is een klasse Readerdie gegevens uit een bestand leest. En waar InputStreamReaderhaalt hij zijn gegevens vandaan? Dat klopt - van een InputStream.

Wanneer u een object maakt , moet u een object of een van zijn onderliggende klassen InputStreamReaderdoorgeven . InputStreamVoorbeeld:

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

De InputStreamReaderklasse heeft alle methoden die de Readerklasse heeft, en ze werken op precies dezelfde manier.

Het belangrijkste verschil tussen de InputStreamReaderklas en bijvoorbeeld FileReaderis waar ze gegevens van lezen. FileReaderleest gegevens uit een bestand (duh — daarom heet het FileReader), maar InputStreamReaderleest gegevens uit een InputStream.

FileReaderWanneer u een teken uit een object leest met behulp van de read()methode, leest het op zijn beurt twee bytes uit het bestand op schijf en retourneert deze als chars.

Wanneer u InputStreamReadermet behulp van de methode een teken uit een object leest read(), leest het op zijn beurt twee bytes van het FileInputStreamobject dat eraan is doorgegeven, dat op zijn beurt gegevens uit het bestand leest. Het resultaat is een keten van aanroepen naar read()methoden.


2. BufferedReaderklasse

Een andere interessante klasse die u waarschijnlijk veel zult gebruiken, is BufferedReader. Dit is ook een "tussenstroom" die gegevens uit een andere stroom leest.

Zoals de naam al doet vermoeden, BufferedReaderis de klasse een subklasse van Readeren kunt u tekens lezen . Maar wat het meest interessant is, is dat je het ook een gegevensbron moet doorgeven in de vorm van een stroom waaruit tekens kunnen worden gelezen , dwz een stroom die de Readerklasse erft.

Wat is het punt? In tegenstelling tot converteert InputStreamReaderde BufferedReaderklasse geen bytes naar tekens: er wordt helemaal niets geconverteerd. In plaats daarvan buffert het gegevens .

Wanneer een programma een enkel teken uit een BufferedReaderobject leest, leest het object in één keer een grote reeks tekens uit de bronstroom. En slaat ze intern op.

Wanneer het volgende teken uit het BufferedReaderobject wordt gelezen, pakt het eenvoudig het volgende teken uit zijn interne bufferarray en retourneert het zonder toegang tot de gegevensbron. Pas als alle tekens in de buffer zijn opgebruikt, leest het een andere grote reeks tekens in.

De BufferedReaderklasse heeft ook een erg handige methode — String readLine(), waarmee je hele reeksen gegevens uit de bronstroom in één keer kunt lezen. U kunt deze methode gebruiken om bijvoorbeeld een bestand te lezen en de inhoud regel voor regel op het scherm weer te geven. Voorbeeld:

We hebben specifiek wat compacte code geschreven om te illustreren hoe handig dit kan zijn. Deze code kan ook met wat meer detail worden geschreven.

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);
   }
}
Maak een FileReadervoorwerp. De gegevensbron is een bestand.
Maak een BufferedReadervoorwerp. De gegevensbron is een FileReader.
Zolang er nog gegevens in de lezer zitten
Lees één regel
Geef de regel weer
Een belangrijk punt:

Als u meerdere streams aan elkaar koppelt, close()hoeft de methode slechts op één ervan te worden aangeroepen. Die stroom roept de methode op zijn gegevensbron aan, enzovoort, totdat close()de laatste gegevensstroom wordt aangeroepen.



3. Lezen vanaf de console

En nog een interessant feit: de Scannerklasse is niets meer dan een tussenliggende invoerstroom die gegevens leest van System.in, wat ook een gegevensstroom is.

Hier zijn twee manieren om een ​​regel van de console te lezen:

Scanner klasse BufferedReader- en 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();

Onze vriend is niets meer dan een statische variabele van de klasse. Het is een wiens naam is .System.ininSystemInputStreamin

Dus bijna vanaf het allereerste begin van je Java-studies op CodeGym, heb je met datastromen gewerkt en daarvan ketens gebouwd. Maar nu ga je het bewuster doen.