A Java programozási nyelvSoós Sándor 1/28 Java programozási nyelv 10. rész – Input/output kezelés Nyugat-Magyarországi Egyetem Faipari Mérnöki Kar Informatikai Intézet Soós Sándor szeptember
A Java programozási nyelvSoós Sándor 2/28 Tartalomjegyzék ● Input/output eszközök a Java-ban ● Csatornák a Java-ban ● Csatornaosztályok a java.io csomagban ● Bájt- és karaktercsatornák ● Szabványos be- és kimenet, hibacsatorna ● Csatornák alapfunkciói ● Adatforrások és adatnyelők ● Hasznos szűrőosztályok ● Egyéb fájlkezelő eszközök a Java-ban
A Java programozási nyelvSoós Sándor 3/28 Input/output eszközök a Java-ban ● A Java csatornák (stream-ek) segítségével valósítja meg az I/O műveletek nagy részét. ● Egy csatorna adatok sorozata, egyik végén befelé a másik végén kifelé "folynak" az adatok. ● A Java program szempontjából vannak bemeneti és kimeneti csatornák. ● A csatornák mellett a Java rendelkezik eszközökkel a közvetlen elérésű fájlok és a helyi fájlrendszerek kezeléséhez is.
A Java programozási nyelvSoós Sándor 4/28 Bemeneti csatornák ● Csak a csatorna elejéről tudunk adatokat elolvasni és levenni ● Tartozik hozzá egy adatforrás, ami adatokkal táplálja a csatornát. ● Az adatforrás sok minden lehet: – billentyűzet – fájl – egy String – egy program – egy hálózati végpont – egy másik csatorna kimenete – stb.
A Java programozási nyelvSoós Sándor 5/28 Kimeneti csatornák ● Csak a csatorna végére tudunk adatokat írni ● Tartozik hozzá egy adatnyelő, ahova a kiírt adatok mennek ● Az adatnyelő sok minden lehet: – képernyő – fájl – egy String – egy program – egy hálózati végpont – egy másik csatorna bemenete – stb.
A Java programozási nyelvSoós Sándor 6/28 Csatornák a Java-ban ● Ahogyan minden mást, a csatornákat is osztályokkal valósítjuk meg a Java-ban. ● Minden csatorna típusnak egy-egy osztály felel meg. ● A csatornákat megvalósító osztályok a java.io csomagban találhatók.
A Java programozási nyelvSoós Sándor 7/28 Csatornaosztályok csoportosítása ● A csatorna iránya alapján vannak: – bemeneti osztályok – kimeneti kimeneti ● A csatornán folyó adatok típusa szerint vannak: – bájtcsatorna-osztályok – karaktercsatorna-osztályok ● Feladatuk szerint vannak – forrás osztályok – nyelő osztályok – a csatornát módosító osztályok
A Java programozási nyelvSoós Sándor 8/28 Az alap csatornaosztályok Típus\Irány BemenetiKimeneti BájtInputStreamOutputStream KarakterReaderWriter ● Az ezekből származó osztályok így végződnek. ● A név végéből tudhatjuk, hogy milyen típusú osztályról van szó. Például: FileInputStream, FileOutputStream, FileReader, FileWriter
A Java programozási nyelvSoós Sándor 9/28 Csatornaosztályok a java.io csomagban (Az ábra JPEG formátumban megtalálható a példák között)
A Java programozási nyelvSoós Sándor 10/28 Bájt- és karaktercsatornák ● A két típus a csatorna által kezelt legkisebb adategység típusában különbözik: – bájt: 8 bit – char: 16 bit, (Unicode) ● A két osztálycsalád nagyon sok szempontból hasonlít egymásra. ● Amit az egyik típusról megtanultunk, azt a másiknál is használhatjuk értelemszerű módosításokkal. ● Például: OutputStream:public void write( byte c[] ) throws IOException Writer:public void write( char c[] ) throws IOException
A Java programozási nyelvSoós Sándor 11/28 Feladat szerinti csoportosítás ● Bemeneti csatornák, forrásosztályok: – Pl. FileInputStream, FileReader ● Kimeneti csatornák, nyelőosztályok: – Pl. FileOutputStream, FileWriter ● Szűrők: – egy meglévő csatornát új képességekkel, tulajdonságokkal egészít ki. Például: – BufferedInputStream, BufferedReader: az InputStream, illetve a Reader pufferelt beolvasást biztosító változata. – A szűrőket mindig egy létező csatornaobjektum "fölé" hozzuk létre, a konstruktorának átadjuk a csatorna objektumot.
A Java programozási nyelvSoós Sándor 12/28 Példa a szűrőkre ● PrintWriter: – a hozzárendelt csatornát kiegészíti a különböző adattípusok szöveges kiírásának képességével. – Konstruktorának meg kell adni egy kimeneti csatornát, ezt fogja kiegészíteni ezzel a képességgel. FileWriter fout = new FileWriter( "printwriter.txt" ); PrintWriter out = new PrintWriter( fout ); vagy PrintWriter out = new PrintWriter( new FileWriter( "printwriter.txt" ) );
A Java programozási nyelvSoós Sándor 13/28 Szabványos be- és kimenet, hibacsatorna ● System.in public static final InputStream in – A standard inputhoz van rendelve a program elindulásakor ● System.out public static final PrintStream out – A standard outputhoz van rendelve a program elindulásakor ● System.err public static final PrintStream err – A standard hibakimenethez van rendelve a program elindulásakor ● Átirányíthatók az operációs rendszer szintjén.
A Java programozási nyelvSoós Sándor 14/28 Csatornák alapfunkciói ● Ezeket a funkciókat a négy alaposztály definiálja: – InputStream, OutputStream, Reader, Writer ● A többi osztály ezektől örökli őket. ● Az alapfunkciók: – Csatorna megnyitása, lezárása – Kiíró műveletek – Olvasó műveletek – Könyvjelző-mechanizmus – Egyéb műveletek
A Java programozási nyelvSoós Sándor 15/28 Csatornák megnyitása és lezárása ● A Java I/O osztályoknak nincsen külön megnyitó metódusa, a konstruktor hozza létre és rögtön meg is nyitja a csatornát. ● A csatorna lezárására a close() metódus szolgál. ● Kimeneti csatornák esetén a close() végrehajtja a flush() metódust is, azaz lemezre menti a pufferek tartalmát. ● Ha lezárt csatornára próbálunk meghívni valamilyen író/olvasó műveletet, akkor IOException kivételt kapunk. ● Például: FileWriter fout = new FileWriter("filenev.txt");... // itt lehet használni a csatornát fout.close();
A Java programozási nyelvSoós Sándor 16/28 Kiíró műveletek ● Mind a bájt, mind a karakter típusú kimeneti csatornák rendelkeznek a következő 3 kiíró metódussal: public void write( int i )throws IOException public void write( byte t[] )throws IOException public void write( byte t[], int off, int len )throws IOException karaktercsatornák esetén byte helyett char értendő ● Az első write metódus a paraméter 1 vagy 2 legalsó bájtját írja ki. ● A karaktercsatornák rendelkeznek a következő 2 metódussal is: public void write( String s )throws IOException public void write( String s, int off, int len )throws IOException
A Java programozási nyelvSoós Sándor 17/28 Olvasó műveletek ● Mind a bájt, mind a karakter típusú kimeneti csatornák rendelkeznek a következő 3 beolvasó metódussal: public int read()throws IOException public int read( byte t[] )throws IOException public int read( byte t[], int off, int len )throws IOException karaktercsatornák esetén byte helyett char értendő ● Az első read metódus 1 vagy 2 bájtot olvas be, majd int-té alakítva adja vissza. ● A másik kettő annyi adatot olvas, amennyi a megadott tömbben, vagy résztömbben elfér. Visszaadja a beolvasott adategységek (byte, vagy char) számát, vagy -1-et, ha nem volt olvasható adat.
A Java programozási nyelvSoós Sándor 18/28 Példa: fájlok másolása ● Az eddig látott eszközökkel már le tudunk másolni fájlokat. ● A write() és a read() metódusokkal bájtról-bájtra másolhatunk: – masolo.java ● A tömbökkel dolgozó read és write metódusokkal viszont pufferelt másolást végezhetünk: – masoloB.java ● Mi a szerepe a pufferelésnek? Mekkora legyen a pufferméret? Miért?
A Java programozási nyelvSoós Sándor 19/28 Hogyan kezeljük a csatorna végét? ● A beolvasó műveletek megkülönböztetik az üres és a véget ért csatornákat. ● Üres egy csatorna, ha pillanatnyilag nem tartalmaz adatot. Ilyenkor a beolvasó műveletek addig várakoznak, amíg nem érkezik adat. ● Véget ért egy csatorna, ha a csatorna végét jelző jel érkezik meg rajta (fájl vége, UNIX-ban Ctrl- D, DOS-ban Ctrl-Z billentyű) ● Nézzük meg a Billentyu.java fájlt!
A Java programozási nyelvSoós Sándor 20/28 Könyvjelző-mechanizmus ● Ezzel a témakörrel nem foglalkozunk részletesen. ● Akit érdekel a dolog nézzen utána a mark, markSupported és a reset metódusoknak!
A Java programozási nyelvSoós Sándor 21/28 Egyéb műveletek ● public long skip( long n ) throws IOException – n darab adategységet átlép beolvasás nélkül – visszaadja a ténylegesen átugrott adategységek számát ● public boolean ready( ) throws IOException – karakter csatornáknál megadja, hogy van-e beolvasható adat. – ha igaz, akkor az egy karaktert beolvasó read() nem blokkolódik ● public int available( ) throws IOException – bájt csatornák esetén megadja, hogy minimálisan hány bájt áll rendelkezésre a csatornán.
A Java programozási nyelvSoós Sándor 22/28 Adatforrások és adatnyelők ● Egy csatorna létrehozásakor meg kell adnunk, hogy milyen fizikai adattároló kapcsolódjon hozzá. A csatorna típusa meghatározza, hogy mi jöhet szóba, a konkrétumokat pedig a konstruktornak adjuk át. ● Például a FileWriter egy fájlhoz csatlakozó kimeneti karaktercsatorna. Létrehozása: – new FileWriter( "filenev.txt" ); ● A következő oldalakon sorra vesszük a leggyakoribb adatforrásokat és adatnyelőket.
A Java programozási nyelvSoós Sándor 23/28 Fájlok ● Ha egy csatornához hozzá akarunk rendelni egy fájlrendszerbeli fájlt, akkor a FileInputStream, FileOutputStream, illetve FileReader vagy FileWriter osztályt kell használnunk. ● A konstruktornak át kell adnunk egy hivatkozást a fájlra Stringként, vagy egy File objektumként. ● Ügyeljünk az elérési út formátumára (rendszerfüggő)! InputStream fst = new FileInputStream( "file.txt") String elv = System.getProperty("file.separator"); Writer wf = new FileWriter(elv+"tmp"+elv+"file.txt"); ● Nézzük meg a fajlnev.java fájlt!
A Java programozási nyelvSoós Sándor 24/28 Bájt- és karaktertömbök, Stringek ● Egy csatornát hozzákapcsolhatunk tömbökhöz, vagy Stringekhez. Ehhez a következő osztályokat használhatjuk: – ByteArrayInputStream – ByteArrayOutputStream – CharArrayReader – CharArrayWriter – StringReader – StringWriter ● Nézzük meg a sw.java fájlt!
A Java programozási nyelvSoós Sándor 25/28 Bájtcsatorna feletti karaktercsatornák ● Az InputStreamReader és az OutputStreamWriter osztályok összekapcsolják a bájt és karakter csatornákat. ● Ezek olyan karaktercsatornák, amelyek bájtcsatornák felett vannak definiálva, 16 bites Unicode karaktereket írunk és olvasunk, de azok 8 bites bájtok formájában utaznak a csatornán. A konstruktornak megadhatjuk, hogy milyen szabvány szerint konvertáljon. ● Lásd Latin2.java!
A Java programozási nyelvSoós Sándor 26/28 Bemeneti csatornák összefűzése ● A SequenceInputStream osztállyal összefűzhetünk több bemeneti csatornát. ● Nézzük meg a papsajt.java fájl-t!
A Java programozási nyelvSoós Sándor 27/28 Hasznos szűrőosztályok ● DataOutputStream, DataInputStream: – különböző adattípusok kiírásával egészíti az eredeti csatornát – Nézzük meg a vacsora.java fájlt! ● PrintStream, PrintWriter: – különböző adattípusok szöveges kiírásával egészíti az eredeti csatornát – Nézzük meg a okos.java fájlt! ● Csatornák bufferelése – BufferedInputStream, BufferedReader, BufferedOutputStream, BufferedWriter – Nézzük meg a sum.java fájlt!
A Java programozási nyelvSoós Sándor 28/28 Egyéb fájlkezelő eszközök a Java-ban ● Nem stream alapú fájlkezelő osztályok: – RandomAccessFile osztály: közvetlen elérésű fájlok – Nézzük meg a raf.java fájlt! ● A helyi fájlrendszer fájljainak kezelése: – File osztály – Nézzük meg a fajlok.java fájlt!