1. InputStreamReaderosztály

A streamek másik érdekes tulajdonsága, hogy több adatfolyamot láncokká kombinálhat . Egy adatfolyam nem csak a belső adatforrásából, hanem egy másik adatfolyamból is képes adatokat olvasni .

Ez egy nagyon hatékony mechanizmus a Java-ban, amely lehetővé teszi összetett adatolvasási forgatókönyvek létrehozását az egyik adatfolyam és a másik összekapcsolásával. Egy ilyen séma így néz ki:

InputStreamReader osztály

Amikor egy program adatokat olvas ki egy adatfolyamból, az adatfolyam viszont az adatforrásból olvassa be az adatokat, amely például egy másik adatfolyam vagy egy fájl.

Ráadásul az egyes adatfolyamok nemcsak beolvasnak és kiadnak adatokat, hanem átalakíthatják azokat, vagy különféle műveleteket hajthatnak végre rajta. Jó példa egy ilyen "köztes folyamra" az InputStreamReaderosztály.

Már ismerünk egy osztályt FileReader– ez egy olyan osztály Reader, amely egy fájlból olvas adatokat. És honnan InputStreamReaderveszik az adatokat? Így van – egy InputStream.

Objektum létrehozásakor InputStreamReaderát kell adnia egy InputStreamobjektumot vagy annak egyik leszármazott osztályát. Példa:

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

Az InputStreamReaderosztályban az összes metódus megtalálható Reader, és pontosan ugyanúgy működnek.

A fő különbség az InputStreamReaderosztály és mondjuk FileReaderaz, hogy honnan olvasnak adatokat. FileReaderbeolvassa az adatokat egy fájlból (duh - ezért hívják FileReader), de InputStreamReaderolvas adatokat egy InputStream.

FileReaderAmikor a metódussal beolvas egy karaktert egy objektumból read(), az viszont beolvas két bájtot a lemezen lévő fájlból, és ként adja vissza őket chars.

InputStreamReaderAmikor a metódus segítségével beolvas egy karaktert egy objektumból read(), az viszont két bájtot olvas be a FileInputStreamneki átadott objektumból, ami viszont adatokat olvas be a fájlból. Az eredmény metódushívások láncolataread() .


2. BufferedReaderosztály

Egy másik érdekes osztály, amelyet valószínűleg sokat fogsz használni, a BufferedReader. Ez is egy "köztes adatfolyam", amely egy másik adatfolyamból olvas adatokat.

Ahogy a neve is sugallja, az BufferedReaderosztály egy alosztálya Reader, és lehetővé teszi a karakterek olvasását . A legérdekesebb azonban az, hogy egy adatforrást is át kell adni neki egy adatfolyam formájában, amelyből a karakterek kiolvashatók , azaz egy adatfolyamot, amely örökli az Readerosztályt.

Mi az értelme? Ellentétben a -val InputStreamReader, az BufferedReaderosztály nem alakítja át a bájtokat karakterekké: egyáltalán nem konvertál semmit. Ehelyett puffereli az adatokat .

Amikor egy program egyetlen karaktert olvas be egy objektumból BufferedReader, az objektum egyszerre egy nagy karaktertömböt olvas ki a forrásfolyamból. És belül tárolja őket.

Amikor a következő karaktert kiolvassák az BufferedReaderobjektumból, egyszerűen megragadja a következő karaktert a belső puffertömbjéből, és visszaadja anélkül, hogy hozzáférne az adatforráshoz. Csak ha a pufferben lévő összes karakter elhasználódott, akkor a karakterek egy másik nagy tömbje olvasható be.

Az BufferedReaderosztálynak van egy nagyon hasznos metódusa is – String readLine(), amely lehetővé teszi, hogy egyszerre teljes adatsort olvasson ki a forrásfolyamból. Ezzel a módszerrel például beolvashatunk egy fájlt, és soronként megjeleníthetjük annak tartalmát a képernyőn. Példa:

Külön írtunk néhány kompakt kódot, amely bemutatja, milyen kényelmes lehet ez. Ezt a kódot kicsit részletesebben is meg lehetne írni.

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);
   }
}
Hozzon létre egy FileReaderobjektumot. Az adatforrás egy fájl.
Hozzon létre egy BufferedReaderobjektumot. Az adatforrás egy FileReader.
Amíg van még adat az olvasóban
Egy sor olvasása
Jelenítse meg a sort
Egy fontos szempont:

Ha több adatfolyamot láncol össze, akkor a close()metódust csak az egyiken kell meghívni. Ez az adatfolyam meg fogja hívni a metódust az adatforrásában, és így tovább, amíg close()meg nem hívják a végső adatfolyamon.



3. Olvasás a konzolról

És még egy érdekesség: az Scannerosztály nem más, mint egy közbenső bemeneti folyam, amely a -ból olvas adatokat System.in, ami szintén adatfolyam.

Kétféleképpen olvashat ki egy sort a konzolról:

Szkenner osztály BufferedReader és BufferedWriter osztályok
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();

A barátunk nem más, mint az osztály statikus változója . Ez egy, akinek a neve .System.ininSystemInputStreamin

Tehát szinte a CodeGym-en végzett Java-tanulmányaid kezdetétől fogva adatfolyamokkal dolgozol, és láncokat építesz belőlük. De most tudatosabban fogod csinálni.