==== Čtení a zápis ==== === Proudy === Pro čtení a zápis do souborů slouží proudy (Streams). Proudy umožňují pouze sekvenční zpracování, tj. data přicházejí v pořadí v jakém byla zapsána. === Práce s proudem === Standardní práce s proudem vypadá takto: - otevření streamu, - čtení/zápis dat z/do streamu, - zavření streamu Java rozlišuje proudy znaků (16 bitové) a proudy bytů (8 bitové). Proudy bytů obsahují ve svém názvu //Stream// a směr toku dat //Input/////Output// vzhledem k programu. Znakové proudy jsou označeny //Reader// (vstupní) a //Writer// (výstupní). Proudy mohou pracovat s různými zdroji, pro jejich rozlišení je uvedeno v názvu třídy. Pro operace se soubory je to klíčové slovo //File//. Znakový proud pro čtení ze souboru je //FileReader//, bytový proud pro zápis do souboru je //FileOutputStream//. Čtení z bytového proudu: FileInputStream fis = new FileInputStream("vstup.bin"); int i; while ((i = fis.read()) != -1) // hodnota -1 znamena konec proudu System.out.println(i); fis.close(); Zápis do bytového proudu: FileOutputStream fos = new FileOutputStream("vystup.bin"); for (int i=0; i < 10; i++) fos.write(i); fos.close(); Čtení po znacích ze znakového proudu: FileReader fr = new FileReader("vstup.txt"); int c; while ((c = fr.read()) != -1) // hodnota -1 znamena konec proudu System.out.print((char) c); fr.close(); Zápis řetězce do znakového proudu: FileWriter fw = new FileWriter("vystup.txt"); fw.write(args[0]); fw.close(); === Spojování proudů === Proudy lze vzájemně spojovat, tj. výstup jednoho proudu lze napojit na vstup druhého proudu. Proudy lze rozdělit na 2 skupiny: proudy pro přímé napojení na zdroj dat (soubor) a proudy pro zpracování výstupu z jiného proudu. Potřebujeme-li propojit dva proudy, předáme první proud jako parametr do konstruktoru druhého proudu. Např. //DataInputStream// a //DataOutputStream// slouží pro čtení a zápis primitivních datových typů: double price = ...; int unit = ...; DataOutputStream dos = new DataOutputStream(new FileOutputStream("invoice.txt")); dos.writeDouble(price); dos.writeChar('\t'); dos.writeInt(units); dos.close(); DataInputStream dis = new DataInputStream(new FileInputStream("invoice.txt")); price = dis.readDouble(); dis.readChar(); unit = dis.readInt(); dis.close(); === Třídy InputStreamReader a OutputStreamWriter === Proudy //InputStreamReader// a //OutputStreamWriter// mají zvláštní postavení. Slouží ke konverzi bytů na znaky a opačně. //InputStreamReader// čte byty z bytového streamu, konvertuje je na znaky a ty předává na výstup. Do proudu typu //OutputStreamWriter// zapisujeme znaky, proud je konvertuje na byty a ty předává na výstup. === Bufferované proudy === Další skupinou proudů jsou bufferované proudy, které umožňují číst několik bytů či znaků najednou. Např. ke čtení textu po řádcích slouží proud //BufferedReader//: String s; InputStreamReader isr = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(isr); while ((s = br.readLine()) != null) { System.out.println(s); } br.close(); === Třída RandomAccessFile === Třída //RandomAccessFile// umožňuje přistupovat k datům v souboru v libovolném pořadí(random, zde neznamená náhodné, protože nepotřebujeme náhodně vybraná data, ale jedna konkrétní z námi určené pozice). byte[] b = "approved".getBytes(); RandomAccessFile raf = new RandomAccessFile("raf.txt","rw"); raf.seek(24); // nastav pozici raf.write(b); // zapis na pozici raf.close(); === Serializace === Serializace slouží k čtení/zápisu objektů, které jsou již složitější než základní datové typy. Proces serializace je zajišťován třídami //ObjectInputStream// a //ObjectOutputStream//, které obsahují metody //readObject()// a //writeObject()//. Pomocí nich lze zapsat nebo přečíst všechna data, která daný objekt v Javě potřebuje. Tatko lze zapisovat objekty tříd, které implementují rozhraní java.io.Serializable. Toto je však splněno pro většinu tříd z Java Core API. Pokud potřebujeme takto pracovat s objekty vlastní třídy, je nutné tuto implementaci zajistit, což není obtížné, neboť rozhraní nemá žádné metody. Vlastní třída však musí mít datové prvky ze základních datových typů nebo tzpů, které již implementovaly rozhraní //Serializable//.