1. Adatfolyamok
Ritkán létezik egy program önmaga szigeteként. A programok általában valamilyen módon kölcsönhatásba lépnek a „külvilággal”. Ez történhet adatok beolvasásával a billentyűzetről, üzenetek küldésével, oldalak letöltésével az internetről, vagy fordítva, fájlok feltöltésével egy távoli szerverre.
Mindezekre a viselkedésekre egy szóval utalhatunk: adatcsere a program és a külvilág között. Várj, ez nem csak egy szó.
Természetesen maga az adatcsere két részre osztható: adatfogadásra és adatküldésre. Például adatokat olvas be a billentyűzetről egy Scanner
objektum segítségével – ez adatokat fogad. És egy parancs segítségével megjeleníti az adatokat a képernyőn System.out.println()
– ez adatküldés.
A programozásban a "folyam" kifejezést az adatcsere leírására használják. Honnan jött ez a kifejezés?
A való életben lehet egy vízfolyásod vagy a tudatfolyamod. A programozásban adatfolyamaink vannak .
A Streams sokoldalú eszköz. Lehetővé teszik a program számára, hogy bárhonnan adatokat fogadjon (bemeneti adatfolyamok), és bárhová küldjön adatokat (output stream). Tehát két típusa van:
- A bemeneti adatfolyam az adatok fogadására szolgál
- A kimeneti adatfolyam adatok küldésére szolgál
Az adatfolyamok „kézzelfoghatóvá” tétele érdekében a Java alkotói két osztályt írtak: InputStream
és OutputStream
.
Az InputStream
osztálynak van egy read()
metódusa, amellyel adatokat olvashat ki belőle. És az OutputStream
osztálynak van egy write()
metódusa, amivel adatokat írhatunk rá. Vannak más módszereik is, de erről később.
Bájtfolyamok
Milyen adatokról beszélünk? Milyen formátumba kerül? Más szóval, milyen adattípusokat támogatnak ezek az osztályok?
Ezek általános osztályok, így támogatják a leggyakoribb adattípust - a byte
. Egy OutputStream
bájtokat (és bájttömböket) írhat, egy InputStream
objektum pedig bájtokat (vagy bájttömböket) olvashat. Ennyi – nem támogatnak semmilyen más adattípust.
Ennek eredményeként ezeket az adatfolyamokat bájtfolyamoknak is nevezik .
A streamek egyik jellemzője, hogy adataik csak szekvenciálisan olvashatók (vagy írhatók). Nem olvashatsz adatokat egy adatfolyam közepéről anélkül, hogy elolvasnád az előtte lévő összes adatot.
Így működik az adatok olvasása a billentyűzetről az Scanner
osztályon keresztül: soronként, soronként olvassa be az adatokat a billentyűzetről. Olvasunk egy sort, majd a következő sort, majd a következő sort, és így tovább. Illetve a sorok olvasásának módszerét nevezzük nextLine()
.
Az adatok írása OutputStream
is szekvenciálisan történik. Jó példa erre a konzol kimenet. Kiírsz egy sort, amit még egy és még egy követ. Ez egy szekvenciális kimenet. Nem lehet kiírni az első sort, majd a tizedet, majd a másodikat. Minden adat csak szekvenciálisan kerül kiírásra a kimeneti adatfolyamba.
Karakterfolyamok
Nemrég tanulta meg, hogy a karakterláncok a második legnépszerűbb adattípusok, és valóban azok. Sok információ kerül átadásra karakterek és egész karakterláncok formájában. A számítógép kiválóan képes mindent bájtban küldeni és fogadni, de az ember nem ilyen tökéletes.
Ezt a tényt figyelembe véve a Java programozók további két osztályt írtak: Reader
és Writer
. Az Reader
osztály hasonló az InputStream
osztályhoz, de a metódusa read()
nem bájtokat olvas, hanem karaktereket ( char
). Az Writer
osztály megfelel az OutputStream
osztálynak. És akárcsak az Reader
osztály, ez is karakterekkel ( char
) működik, nem bájtokkal.
Ha ezt a négy osztályt összehasonlítjuk, a következő képet kapjuk:
Bájtok (byte) | Karakterek (karakterek) | |
---|---|---|
Adatok olvasása |
|
|
Adatok írása |
|
|
Praktikus alkalmazás
Magukat a InputStream
, OutputStream
, Reader
és Writer
osztályokat senki nem használja közvetlenül, mivel nincsenek olyan konkrét objektumokhoz társítva, amelyekből adatokat le lehet olvasni (vagy amibe adatokat lehet írni). De ennek a négy osztálynak rengeteg leszármazottja van, amelyek sok mindenre képesek.
2. InputStream
osztály
Az InputStream
osztály azért érdekes, mert több száz leszármazott osztály szülőosztálya. Nincsenek saját adatai, de vannak olyan metódusai, amelyeket az összes származtatott osztály örököl.
Általában ritkán fordul elő, hogy a stream objektumok belsőleg tároljanak adatokat. A stream egy eszköz az adatok olvasására/írására, de nem tárolására. Mondjuk, vannak kivételek.
InputStream
Az osztály és az összes leszármazott osztály módszerei :
Mód | Leírás |
---|---|
|
Egy bájtot olvas be az adatfolyamból |
|
Egy bájttömböt olvas be az adatfolyamból |
|
Beolvassa az összes bájtot az adatfolyamból |
|
Bájtokat kihagy n az adatfolyamban (elolvassa és eldobja) |
|
Ellenőrzi, hogy hány bájt maradt az adatfolyamban |
|
Bezárja a patakot |
Nézzük röviden ezeket a módszereket:
read()
módszer
A read()
metódus beolvas egy bájtot a folyamból, és visszaadja azt. Megzavarhatja a int
visszatérési típus. Ezt a típust választották, mert int
ez a szabványos egész típus. int
A lesz első három bájtja nulla.
read(byte[] buffer)
módszer
Ez a read()
módszer második változata. Lehetővé teszi, hogy egy bájttömböt InputStream
egyszerre olvasson ki. A bájtokat tároló tömböt argumentumként kell átadni. A metódus egy számot ad vissza – a ténylegesen beolvasott bájtok számát.
Tegyük fel, hogy van egy 10 kilobájtos puffered, és adatokat olvasol egy fájlból az FileInputStream
osztály segítségével. Ha a fájl csak 2 kilobájtot tartalmaz, akkor az összes adat betöltődik a puffertömbbe, és a metódus a 2048 (2 kilobájt) számot adja vissza.
readAllBytes()
módszer
Nagyon jó módszer. Csak beolvassa az összes adatot a -tól kezdve, InputStream
amíg el nem fogy, és egy bájtos tömbként adja vissza. Ez nagyon hasznos kis fájlok olvasásához. Előfordulhat, hogy a nagy fájlok fizikailag nem férnek el a memóriában, és a módszer kivételt jelent.
skip(long n)
módszer
Ez a módszer lehetővé teszi az első n bájt kihagyását az objektumból InputStream
. Mivel az adatok olvasása szigorúan szekvenciálisan történik, ez a módszer egyszerűen beolvassa az első n bájtot az adatfolyamból, és eldobja azokat.
A ténylegesen kihagyott bájtok számát adja eredményül (ha az adatfolyam a n
bájtok kihagyása előtt ért véget).
int available()
módszer
A metódus az adatfolyamban még hátralévő bájtok számát adja vissza
void close()
módszer
A close()
metódus bezárja az adatfolyamot, és felszabadítja a hozzá tartozó külső erőforrásokat. Egy adatfolyam bezárása után nem lehet több adatot kiolvasni belőle.
Írjunk egy példaprogramot, amely egy nagyon nagy fájlt másol. Nem használhatjuk a readAllBytes()
módszert a teljes fájl memóriába olvasására. Példa:
Kód | jegyzet |
---|---|
|
InputStream fájlból való olvasáshoz fájlba OutputStream íráshoz Puffer, amelybe beolvassuk az adatokat Amíg van adat a folyamban Adatok olvasása a pufferbe Írja az adatokat a pufferből a második adatfolyamba |
Ebben a példában két osztályt használtunk: FileInputStream
a leszármazottja InputStream
a fájlból való adatok olvasásához, és FileOutputStream
a leszármazottja OutputStream
az adatok fájlba írásához. A második óráról kicsit később beszélünk.
Egy másik érdekes pont itt a real
változó. Amikor az utolsó adatblokkot beolvassák egy fájlból, könnyen előfordulhat, hogy 64 KB-nál kevesebb adat van benne. Ennek megfelelően nem a teljes puffert kell kiadnunk, hanem annak csak egy részét - az első real
bájtokat. Pontosan ez történik a módszerben write()
.
3. Reader
osztály
Az Reader
osztály az osztály teljes analógja InputStream
. Az egyetlen különbség az, hogy karakterekkel ( char
) működik, bájtokkal nem. Csakúgy, mint az InputStream
osztály, az Reader
osztály önmagában sehol nem használatos: több száz leszármazott osztály szülőosztálya, és mindegyikhez közös metódusokat határoz meg.
Reader
Az osztály (és az összes leszármazott osztály) módszerei :
Mód | Leírás |
---|---|
|
Olvas egyet char a patakból |
|
Beolvas egy char tömböt az adatfolyamból |
|
Kihagyja n chars az adatfolyamot (elolvassa és eldobja őket) |
|
Ellenőrzi, hogy maradt-e még valami az adatfolyamban |
|
Bezárja a patakot |
A módszerek nagyon hasonlóak az osztály módszereihez InputStream
, bár vannak apró eltérések.
int read()
módszer
Ez a metódus beolvas egyet char
a folyamból, és visszaadja. A char
típus kiszélesedik -re int
, de az eredmény első két bájtja mindig nulla.
int read(char[] buffer)
módszer
Ez a read()
módszer második változata. Lehetővé teszi egy char tömb beolvasását egyből Reader
. A karaktereket tároló tömböt argumentumként kell átadni. A metódus egy számot ad vissza – a ténylegesen beolvasott karakterek számát.
skip(long n)
módszer
Ez a módszer lehetővé teszi az objektum első n karakterének kihagyását Reader
. Pontosan ugyanúgy működik, mint az InputStream
osztály analóg metódusa. A ténylegesen kihagyott karakterek számát adja vissza.
boolean ready()
módszer
Akkor tér vissza true
, ha vannak olvasatlan bájtok az adatfolyamban.
void close()
módszer
A close()
metódus bezárja az adatfolyamot, és felszabadítja a hozzá tartozó külső erőforrásokat. Egy adatfolyam bezárása után nem lehet több adatot kiolvasni belőle.
Összehasonlításképpen írjunk egy programot, amely szöveges fájlt másol:
Kód | jegyzet |
---|---|
|
Reader fájlból való olvasáshoz fájlba Writer íráshoz Puffer, amelybe beolvassuk az adatokat Amíg van adat a folyamban Adatok olvasása pufferbe Írja az adatokat a pufferből a második adatfolyamba |
GO TO FULL VERSION