1. InputStreamReaderklass

En annan intressant egenskap hos strömmar är att du kan kombinera flera strömmar tillsammans till kedjor . En ström kan läsa data inte bara från sin interna datakälla, utan också från en annan ström .

Detta är en mycket kraftfull mekanism i Java, som gör det möjligt att skapa komplexa dataläsningsscenarier genom att koppla en ström till en annan. Ett sådant schema ser ut så här:

InputStreamReader-klass

När ett program läser data från en dataström läser dataströmmen i sin tur data från sin datakälla, som till exempel är en annan dataström eller en fil.

Dessutom läser varje dataström inte bara in och ger ut data, utan kan också transformera den eller utföra olika operationer på den. Ett bra exempel på en sådan "mellanström" är InputStreamReaderklassen.

Vi känner redan till en klass som heter FileReader— det är en Readersom läser data från en fil. Och var InputStreamReaderfår dess data ifrån? Det stämmer - från en InputStream.

När du skapar ett InputStreamReaderobjekt måste du skicka in ett InputStreamobjekt eller en av dess underordnade klasser. Exempel:

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

Klassen InputStreamReaderhar alla metoder som Readerklassen har, och de fungerar på exakt samma sätt.

Den största skillnaden mellan InputStreamReaderklassen och till exempel FileReadervar de läser data från. FileReaderläser data från en fil (duh — det är därför det heter ), FileReadermen InputStreamReaderläser data från en InputStream.

När du läser ett tecken från ett FileReaderobjekt med read()metoden läser det i sin tur två byte från filen på disken och returnerar dem som chars.

När du läser ett tecken från ett InputStreamReaderobjekt med read()metoden läser det i sin tur två byte från FileInputStreamobjektet som skickas till det, vilket i sin tur läser data från filen. Resultatet är en kedja av anrop till read()metoder.


2. BufferedReaderklass

En annan intressant klass som du sannolikt kommer att använda mycket är BufferedReader. Detta är också en "mellanström" som läser data från en annan ström.

Som namnet antyder BufferedReaderär klassen en underklass av Readeroch låter dig läsa tecken . Men det som är mest intressant är att du också behöver skicka den en datakälla i form av en ström från vilken tecken kan läsas , alltså en ström som ärver Readerklassen.

Vad är poängen? Till skillnad från InputStreamReader, konverterar klassen BufferedReaderinte bytes till tecken: den konverterar ingenting alls. Istället buffrar den data .

När ett program läser ett enstaka tecken från ett BufferedReaderobjekt, läser objektet ett stort antal tecken från dess källström på en gång. Och lagrar dem internt.

När nästa tecken läses från objektet BufferedReader, tar det helt enkelt nästa tecken från dess interna buffertmatris och returnerar det utan att komma åt datakällan. Först när alla tecken i bufferten är förbrukade läses den in ytterligare ett stort antal tecken.

Klassen BufferedReaderhar också en mycket användbar metod — , String readLine()som låter dig läsa hela datasträngar från källströmmen på en gång. Du kan använda den här metoden för att till exempel läsa en fil och visa dess innehåll på skärmen rad för rad. Exempel:

Vi skrev specifikt lite kompakt kod för att illustrera hur bekvämt detta kan vara. Denna kod kan också skrivas med lite mer detaljer.

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);
   }
}
Skapa ett FileReaderobjekt. Datakällan är en fil.
Skapa ett BufferedReaderobjekt. Datakällan är en FileReader.
Så länge det fortfarande finns data i läsaren
Läs en rad
Visa raden
En viktig punkt:

Om du kopplar ihop flera strömmar, close()behöver metoden bara anropas på en av dem. Den strömmen kommer att anropa metoden på sin datakälla, och så vidare, tills close()den anropas på den slutliga dataströmmen.



3. Läser från konsolen

Och ytterligare ett intressant faktum: Scannerklassen är inget annat än en mellanliggande ingångsström som läser data från , System.insom också är en dataström.

Här är två sätt att läsa en rad från konsolen:

Skannerklass Klasserna BufferedReader och BufferedWriter
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();

Vår vän är inget annat än en statisk variabel i klassen. Det är en som heter .System.ininSystemInputStreamin

Så nästan från början av dina Java-studier på CodeGym har du arbetat med dataströmmar och byggt kedjor från dem. Men nu kommer du att göra det mer medvetet.