Vstupy a výstupy v Jave. Obsah Vstupy a výstupy v Jave ...............................................................................................1 Koncepce vstupně/výstupních operací v Jávě............................................................................1 Práce se soubory .................................................................................................................2 TndaFileWlICIPFrílA ....................................................................................................3 Tli* tni- Fil ■■ Lnibi Třída FileWltlPFDIA (2) ...............................................................................................4 ílir rni- Fib i. Lbbibi Třída FileWlKlPEDlA (3) ...............................................................................................5 Flip tni" Fil i. liniki Práce s adresáři...................................................................................................................5 Práce s binárními proudy ......................................................................................................5 Vstupní binární proudy.........................................................................................................6 Důležité neabstraktní třídy odvozené od InputStreamWlKCIPRÍJlA ........................................6 "TJir Fni- Fih i. L^viLi Další vstupní proudy............................................................................................................7 Práce se znakovými proudy...................................................................................................7 Výstupní proudy .................................................................................................................8 Konverze: znakové <-> binární proudy....................................................................................9 Serializace objektů ..............................................................................................................9 Odkazy ...........................................................................................................................10 Vstupy a výstupy v Jávě Koncepce I/O proudů v Jávě, skládání (obalování vlastnostmi) Práce se soubory a adresáři, třída File Binární proudy, abstraktní třídy InputStream, OutputStream Znakové proudy, abstraktní třídy Reader, Writer Serializace objektů Koncepce vstupně/výstupních operací v Jávě založeny na v/v proudech plně platformově nezávislé V/V proudy jsou 1 Vstupy a výstupy v Jave. • znakové (ReaderWllCIPFillA Hli r rnn1 Pil i. Laa-ib i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=Reader]/Writer WlKlPFMA [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=Writer]) nebo • binárni (InputStream/OutputStreamWlICIPFillA [http://cs.wikipedia.org/wiki/Speci%C3 %Alln%C3%AD:Search?search=InputStream/OutputStream ]) koncipovány jako "stavebnice" - lze vkládat do sebe a tím přidávat vlastnosti, např. is = new InputStream(...); bis = new BufferedlnputStream(is) ; Téměř vše ze vstupních/výstupních tříd a rozhraní jev balíku j ava. io. počínaje Java 1.4 se rozvíjí alternativní balík - j ava. ni o WIK1PFFHA ľlír p m- pil i. l-BBib ■ [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search= java.nio ] (New I/O), zde se ale budeme věnovat klasickým I/O z balíku j ava. ioWlKlPFľJlA ill r Mi1 Fib i. Ľ ■■!> ■ [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=java.io]. Blíže viz dokumentace API balíků javaio [http://java.sun.eom/j2se/l.5/docs/api/java/io/package-summary.html], java.nio [http://java.sun.eom/j2se/l.5/docs/api/java/nio/package-summary.html]. Práce se soubory vše je opět v balíku j ava. i oWIKIPFMA íli p p pit rib ■■ Laa-ib i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=java.io] základem je třída java.io.File WlKIPFľllA TVir Pfi-i- Flau L fill i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=java.io.File ] - nositel jména souboru, jakási "brána" k íýzickým souborům na disku. používá se jak pro soubory, tak adresáře, linky i soubory identifikované UNC jmény (\\počítač\adresář...) opět plně platformově nezávislé na odstínění odlišností jednotlivých systémů souborů lze použít vlastností (uvádíme jejich hodnoty pro JVM pod systémem MS Windows): • File.separatorChar \ WlKIPFillA 1»r Tn-i-Fia i. L^iiLi [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=File.separatorChar \ ] - ja- 2 Vstupy a výstupy v Jave. ko charWlKIPFMA Imp p pit riL i. Laanbi [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=char] • File, separator \ WlKIPFFUA [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=File.separator \ ] - jako StringWlKIPFMA —i" 11 T. i.ň.iT. [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=String] • File.pathSeparatorChar ľlip tm1 Fib i. Lniki [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=File.pathSeparatorChar ;] -jako charWHÍlPFTHA Rip ŕni" Fik u Lniki [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=char] • File.pathSeparator /WlKlPFľllA íli r p n t riL i. L" iini i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=File.pathSeparator ;] - jako StringWltlPFľllA "Hip p'pi-i- Fib ■_ L^b-iL i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=String] • System. getProperty ( "user . dir" ) WUflPFľllA Thr p pi t pil ■■ I ■■■nb i [http://cs.wikipedia.org/wiki/Speci%C3 %Alln%C3%AD:Search?search=System.getProperty("user. dir")] - adresář uživatele, pod jehož UID je proces JVM spuštěn Třída PileSEHKíS [http://cs.wikipedia.Org/wiki/Speci%C3%A1ln%C3%AD:S earch?search=File] Vytvoření konstruktorem - máme několik možností: new File(Stňng filename) vytvoří v aktuálním adresáři soubor s názvem filename new File(File baseDir, Stáng file- vytvoří v adresáři baseDir soubor s názvem filename name) new File(String baseDirName, vytvoří v adresáři se jménem baseDirName soubor s názvem fiůe- Stňngfilename) name new File(URL urí) vytvoří soubor se (souborovým - file:) URL url Testy existence a povahy souboru: boolean exists() test na existenci souboru (nebo adresáře) 3 Vstupy a výstupy v Jave. boolean isFile() boolean isDirectoryO test, zda jde o soubor (tj. ne adresář) test, zda jde o adresář Test práv ke čtení/zápisu: boolean canRead() boolean canWrite() test, zda lze soubor číst test, zda lze do souboru zapisovat Třída File™™1* [http://cs.wikipedia.Org/wiki/Speci%C3%A1ln%C3%AD:S earch?search=File] (2) Vytvoření souboru nebo adresáře: boolean createNewFile() boolean mkdir() boolean mkdirs() (pro soubor) vrací tru eWlKfíT.TllA Tip tni1 Fil i. l-aiifc ■ [http://cs.wikipedia.Org/wiki/Speci%C3%A11n%C3%AD:Search7s earch=true], když se podaří soubor vytvořit (pro adresář) vrací tru "TTir Fni- Pil i_ LniLi [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?s earch=true], když se podaří adresář vytvořit navíc si dotvoří i příp. neexistující adresáře na cestě Vytvoření dočasného (temporary) souboru: static File createTempFile(String vytvoří dočasný soubor ve standardním pro to určeném adresáři prefix, String suffix) (např. c:\tempWlrlPFTJlA ill r priT Fík i. Laanb i [http://cs.wikipedia.Org/wiki/Speci%C3%A11n%C3%AD:Search? search=c:\temp]) s uvedeným prefixem a sufixem názvu static File createTempFile(String dtto, ale vytvoří dočasný soubor v adr. directory prefix, String suffix, File directory) Wl KiPEf JlA [http://cs.wikipedia.Org/wiki/Speci%C3%A11n%C3%AD:Search? search=directory] Zrušení: boolean delete() zrušení souboru nebo adresáře 4 Vstupy a výstupy v Jave. Přejmenování (ne přesun mezi adresáři!): boolean renameTo(File dest) přejmenuje soubor nebo adresář Třída FiieSHKS [http://cs.wikipedia.Org/wiki/Speci%C3%A1ln%C3%AD:S earch?search=File] (3) Další vlastnosti: long lengthO délka (velikost) souboru v bajtech long lastModifiedO čas poslední modifikace v ms od začátku éry - podobně jako sys- témový čas vracený System.currentTimeMillis(). String getNameO jen jméno souboru (tj. poslední část cesty) String getPath() celá cesta k souboru i se jménem String getAbsolutePath() absolutní cesta k souboru i se jménem String getParentO adresář, v němž je soubor nebo adresář obsažen Blíže viz dokumentace API třídy File [http://java.sun.eom/j2se/l.5/docs/api/java/io/File.html]. Práce s adresáři Klíčem je opět třída FileWllCIPEMA l"ir Fni1 Fib ■■ Lnibi [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=File] - použitelná i pro adresáře Jak např. získat (filtrovaný) seznam souborů v adresáři? pomocí metody File[] listFiles (FileFilter f f) WllCIPRIllA Ikr km- Fil i. L^ibi [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=File[] lisťFiles(FileFilter ff)] nebo podobné File[] lisťFiles(FilenameFilterfnf): FileFilter je rozhraní s jedinou metodou boolean accept(File pathname), obdobně FilenameFilter, viz Popis APIjava.io.FilenameFilter [http://java.sun.eom/j2se/l.5/docs/api/java/io/FilenameFilter.html] Práce s binárními proudy 5 Vstupy a výstupy v Jave. Vstupní jsou odvozeny od abstraktní třídy InputStreamWlfCIPFľJlA Hli r priT Fib i. Laanb i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=InputStream] Výstupní jsou odvozeny od abstraktní třídy OutputStreamWlfCIPEDlA Th r p n i ■ pil i. I - ■ ■ i b ■ [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=OutputStream] Vstupní binární proudy Uvedené metody, kromě abstract byte read(), nemusejí být nutně v neabstraktní podtřídě překryty. void closeO uzavře proud a uvolní příslušné zdroje (systémové "file handles" apod.) void mark(int readlimit) poznačí si aktuální pozici (později se lze vrátit zpět pomocí re- setO)... boolean markSupportedO ...ale jen když platí tohle abstract int read() přečte bajt (0-255 pokud OK; jinak -1, když už není možné pře- číst) int read(byte[] b) přečte pole bajtů int read(byte[] b, int off, int len) přečte pole bajtů se specifikací délky a pozice plnění pole b void resetO vrátí se ke značce nastavené metodou mark(int) long skip(long n) přeskočí zadaný počte bajtů Důležité neabstraktní třídy odvozené od inputstream WlICIPFillA — i " 11T..:. ň.:r. [http://cs.wikipedia.org/wiki/Speci%C3%A1ln%C3%AD:S earch?search=lnputStream] java.io.FilterInputStream - je bázová třída k odvozování všech vstupních proudů přidávajících vlastnost/ schopnost filtrovat poskytnutý vstupní proud. Příklady filtrů (ne všechny jsou v Java. ioWlKIPEDlA TV» F^v F.. . Lr.V* [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=java.io]!): BufferedlnputStream proud s vyrovnávací pamětí (je možno specifikovat její optimální velikost) java.util.zip.CheckedInputStream proud s kontrolním součtem (např. CRC32) 6 Vstupy a výstupy v Jave. j avax. crypto. CipherlnputStream DatalnputStream java.security.DigestInputStream j ava.util. zip. InflaterlnputStream LineNumberlnputStream ProgressMonitorlnputStream PushbacklnputStream proud dešifrující data ze vstupu má metody pro čtení hodnot primitivních typů, např. float readFloat () WlVIPEDlA Tiř tni1 Fil i. l-aiib i [http://cs.wikipedia.Org/wiki/Speci%C3%A11n%C3%AD:Search? search=float readFloat()] počítá současně i haš (digest) čtených dat, použitý algoritmus lze nastavit dekomprimuje (např. GZIPem) zabalený vstupní proud (má ještě specializované podtřídy) doplňuje informaci o tom, ze kterého řádku vstupu čteme (zavrhovaná - deprecated - třída) přidává schopnost informovat o průběhu čtení z proudu do proudu lze data vracet zpět Další vstupní proudy Příklad rekonstrukce objektů ze souborů FilelnputStream istream = new FilelnputStream("t.tmp"); ObjectlnputStream p = new ObjectlnputStream(istream); int i = p.readlntO; String today = (String)p.readObject(); Date date = (Date)p.readObject(); istream.close(); ja- vstupní proud zvukových dat vax. sound, sampled. AudioInputStre gftteArraylnputStream proud dat čtených z pole bajtů PipedlnputStream SequencelnputStream ObjectlnputStream roura napojená na "protilehlý" PipedOutputStream proud vzniklý spojením více podřízených proudů do jednoho virtuálního proud na čtení serializovaných objektů Práce se znakovými proudy základem je abstraktní třída Reade rWlKIPEMA [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=Reader], konkrétními imple- 7 Vstupy a výstupy v Jave. mentacemijsou: • BufferedReade rWlKIPFMA Flip tni- Fil ■■ L-iBik i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=BufferedReader], Cha-rArrayReaderWlKlPFMA Flip pni" Fil ■■ Lniki [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=CharArrayReader], In- putStreamReaderWlKIPFÍJlA ľlír pni" Fil ■■ Ľaaib i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=InputStreamReader], Pi-pedReaderWlKtPFTllA Tnr rni- ml i. ĽiiiL i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=PipedReader], Strin-gReaderWlKIPFÍHA Tnr pm- Fib i. Lniki [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=StringReader] • LineNumberReaderWHCIPFľJlA Tnr rm- Fil i. l-iinl i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=LineNumberReader], Fi-leReaderWlKIPFDlA Tnr Fm- Fil i. uniii [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=FileReader], Pushbac-kReaderWlKIPFDlA Thr rni- Fil i. L-^a-iL ■ [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=PushbackReader] Výstupní proudy nebudeme důkladně probírat všechny typy principy: • jedná se o protějšky k vstupním proudům, názvy jsou konstruovány analogicky (např. Fi 1 e Re a-derWimPFHlA íli r rm- Fil i. u n iL ■ [http://cs.wikipedia.org/wiki/Speci%C3%A11n%C3%AD: Search?search=FileReader] -> Fi 1 eWr i -terWlKIPFMA Thr FVi-i- Fil i. L-h-iL i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=FileWriter]) místo generických metod readWlKlPFUlA TTir F ni1 Fil u k nikl [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=read] mají write (...) WIKIPFMA [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=write(...)] — i r 11 T..:.r"j. :T~i Příklady: PrintStream poskytuje metody pro pohodlný zápis hodnot primitivních typů a řetězců - příkladem Vstupy a výstupy v Jave. jsou System. outWlfCIPFMA Hli r rnn1 Pil i. Laanb i [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=System.out] a System. errWlKlfľ.UI A Tlir ľni- Fia ■ L^«VLi [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=System.err] Print Writer poskytuje metody pro pohodlný zápis hodnot primitivních typů a řetězců Konverze: znakové <-> binární proudy Ze vstupního binárního proudu InputStreamWlfCIPEfllA TTir Fni- Fil u L-bbibi [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=InputStream] (čili každého) je možné vytvořit znakový ReaderWlKlPľ.lJlA — i " 11T :, ŕj.:r_ [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=Reader] pomocí // nejprve binárni vstupni proud - toho kódováni znaků nezajimá InputStream is = ... // znakový proud isr // použije pro dekódováni standardni znakovou sadu Reader isr = new InputStreamReader(is); // sady jsou definovány v baliku j ava. nioWIKIPFľllA [http://cs.wikipedia.org/wiki/ ílír rn-i- Fík ■■ L-aa-ik ■ Charset chrs = java.nio.Charset.forName("ISO-8859-2"); // znakový proud isr2 // použije pro dekódováni jinou znakovou sadu Reader isr2 = new InputStreamReader(is, chrs); Podporované názvy znakových sad naleznete na webu IANA Charsets [http://www.iana.org/assignments/character-sets]. Obdobně pro výstupní proudy - lze vytvořit Writer z OutputStream. Serializace objektů • nebudeme podrobně studovat, zatím stačí vědět, že: • serializace objektů je postup, jak z objektu vytvořit sekvenci bajtů persistentně uložitelnou na paměťové médium (disk) a později restaurovatelnou do podoby výchozího javového objektu. • deserializace je právě zpětná rekonstrukce objektu • aby objekt bylo možno serializovat, musí implementovat (prázdné) rozhraní ja- 9 Vstupy a výstupy v Jave. WIKIPFMA ílír rni- Fib i. ľiiii i [http://cs.wikipedia.org/wiki/Speci%C3 %Alln%C3%AD:Search?search=java.io.Serializable] • proměnné objektu, které nemají být serializovány, musí být označeny modifikátorem - klíčovým slovem - transient WHCIPFľJlA Tli r hm- Fík ■■ Lnibi [http://cs.wikipedia.org/wiki/Speci%C3 %Alln%C3%AD:Search?search= transient] • pokud požaduje "speciální chovaní" při de/serializaci, musí objekt definovat metody • private void readObject(java.io.ObjectlnputStream stream) throws IOException, ClassNotFoundExceptionWlKI fT.lil A Tlip phi1 Fib u L n hi bi [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=private void readOb-ject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException] • private void writeObject(java.io.ObjectOutputStream stream) throws IOException WlKlPl-.IJI A [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=private void write-Object(java.io.ObjectOutputStream stream) throws IOException] • metody: • DataOutputStream.writeObject (Object o) WlKIPFillA Thr rmr Fib k Lniki [http://cs.wikipedia.org/wiki/Speci%C3%Alln%C3%AD:Search?search=DataOutputStream.writ eObject(Object o)] Odkazy Tutoriály k Java I/O: kapitola z Sun Java Tutorial [http://java.sun.com/docs^oks/tutorial/essential/io/] Demo programy na serializaci (z učebnice): Serializace objektů [http://www.fi.muni.cz/~tomp/java/ucebnice/javasrc/tomp/ucebnice/serializace/] 10