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 2005. szeptember
A Java programozási nyelv
Soós Sándor
1/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 nyelv
Soós Sándor
2/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 nyelv
Soós Sándor
3/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 nyelv
Soós Sándor
4/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 nyelv
Soós Sándor
5/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 nyelv
Soós Sándor
6/28
Csatornaosztályok csoportosítása ●
A csatorna iránya alapján vannak: – –
●
A csatornán folyó adatok típusa szerint vannak: – –
●
bemeneti osztályok kimeneti kimeneti 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 nyelv
Soós Sándor
7/28
Az alap csatornaosztályok
● ●
Típus\Irány
Bemeneti
Kimeneti
Bájt
InputStream
OutputStream
Karakter
Reader
Writer
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 nyelv
Soós Sándor
8/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 nyelv
Soós Sándor
9/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 nyelv
Soós Sándor
10/28
Feladat szerinti csoportosítás ●
Bemeneti csatornák, forrásosztályok: –
●
Kimeneti csatornák, nyelőosztályok: –
●
Pl. FileInputStream, FileReader 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 nyelv
Soós Sándor
11/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 nyelv
Soós Sándor
12/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 nyelv
Soós Sándor
13/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 nyelv
Soós Sándor
14/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 nyelv
Soós Sándor
15/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 nyelv
Soós Sándor
16/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 nyelv
Soós Sándor
17/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: –
●
A tömbökkel dolgozó read és write metódusokkal viszont pufferelt másolást végezhetünk: –
●
masolo.java
masoloB.java
Mi a szerepe a pufferelésnek? Mekkora legyen a pufferméret? Miért?
A Java programozási nyelv
Soós Sándor
18/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 CtrlD, DOS-ban Ctrl-Z billentyű) Nézzük meg a Billentyu.java fájlt!
A Java programozási nyelv
Soós Sándor
19/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 nyelv
Soós Sándor
20/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 nyelv
Soós Sándor
21/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 nyelv
Soós Sándor
22/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 nyelv
Soós Sándor
23/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 nyelv
Soós Sándor
24/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 nyelv
Soós Sándor
25/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 nyelv
Soós Sándor
26/28
Hasznos szűrőosztályok ●
DataOutputStream, DataInputStream: – –
●
PrintStream, PrintWriter: – –
●
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! 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 nyelv
Soós Sándor
27/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!
A Java programozási nyelv
Soós Sándor
28/28