Ezek közül a példaprogramok közül jónéhány fájlokkal dolgozik. Annak, hogy valamelyik nem működik, lehet az az oka, hogy nincs joga fájlokat olvasni vagy létrehozni. Például a vacsora.java program megpróbál létrehozni egy "vacsora.van" fájlt. Ha a programot a CD-ről futtatjuk, a fájl létrehozása sikertelen lesz, hiszen a CD-re nem tud ráírni a program. Ebben az esetben célszerű a programot például egy merevlemezről indítani.
Láthatóvá tesszük a java.io csomag tartalmát,
deklarálunk egy csatorna változót, létrehozunk egy csatornát,
majd le is zárjuk a csatornaobjektumot.
import java.io.*; // ez minden példánkhoz kell ... FileWriter fout = new FileWriter("nyolcna.a"); // megnyitás ... // itt lehet pl. írni a fájlba fout.close(); // lezárásA teljes program: megnyit.java |
Egy kimeneti csatornára kiírjuk egy tömb tartalmát kétféleképpen.
fout.write(tömb); fout.write(tömb,0,tömb.length);A teljes program: kiir.java |
Az in bemenet átmásolása az out kimenetre
bájtonként.
public static void másol( InputStream in, OutputStream out ) throws IOException { int b; while( (b=in.read()) != -1 ) out.write(b); out.flush(); }A teljes program: masolo.java |
Az in bemenet átmásolása az out kimenetre
100 bájtos blokkonként.
static int BlokkMéret = 100; public static void másolBlokkonként( InputStream in, OutputStream out ) throws IOException { byte[] b = new byte[BlokkMéret]; int hossz; while( (hossz=in.read(b)) == BlokkMéret ) out.write(b); if( hossz != -1 ) out.write(b,0,hossz); out.flush(); }A teljes program: masoloB.java |
Kétszer kiírjuk az in csatorna tartalmát a képernyőre.
public static void kétszer( ByteArrayInputStream in ) throws IOException { int c; in.mark(in.available()); while( (c=in.read()) != -1 ) System.out.println(c); in.reset(); // mégegyszer írjuk ki ugyanazt while( (c=in.read()) != -1 ) System.out.println(c); }A teljes program: ketszerezo.java |
Egy fájl-csatornaobjektum létrehozásakor a fájlnév megadása például
így történhet.
InputStream inf = new FileInputStream("olvass.el"); String elv = System.getProperty("file.separator"); Writer wf = new FileWriter(elv + "tmp" + elv + "torolj.le");A teljes program: fajlnev.java |
Egy fájl méretét így kaphatjuk meg:
public static int méret( String fnév ) throws IOException { return (new FileInputStream(fnév)).available(); }A teljes program: fajlmeret.java |
Példa az alábbi szakaszban található: Bájtcsatornák felett létrehozott karaktercsatornák
Egy tömb felett definiált bemeneti csatorna tartalma a tömbbel együtt
változik.
char[] t = {'r', 'ó', 'k', 'a'}; CharArrayReader in = new CharArrayReader(t); t[0] = 'f'; System.out.println(in.read()=='f'); // "true"-t fog kiírniA teljes program: foka.java |
A könyvjelző mechanizmus működése ezeknél a csatornáknál.
char[] t = {'r', 'ó', 'k', 'a'}; CharArrayReader in = new CharArrayReader(t,2,2); int c = in.read(); // c értéke 'k' in.reset(); c = in.read(); // c értéke ismét 'k' (a JDK 1.1-ben 'r')A teljes program: roka.java |
Csőcsatornákat hozunk létre és kapcsolunk össze, majd felettük
karaktercsatornákat definiálunk, különböző karakterkódolással
a cső két végén.
PipedInputStream is = new PipedInputStream(); PipedOutputStream os = new PipedOutputStream(is); Reader r = new InputStreamReader(is,"8859_1"); Writer w = new OutputStreamWriter(os,"MacCyrillic"); w.write('÷'); w.flush(); // a 247-es kódú karakter kerül a csatornára System.out.println(r.read()); // a képernyőn 214 jelenik megA teljes program: kulonbozo.java |
Az ISO Latin-1 kódolásban nincsen O" betű, ezért a kimeneten a
\u0150 kódú karakter helyén kérdőjel jelenik meg:
tekn?c
Writer w = new OutputStreamWriter(System.out,"8859_1"); w.write("tekn\u0150c"); w.close();A teljes program: teknoc.java |
Két bemeneti csatornát összefűzhetünk. Miután az elsőről (itt a "papsajt"
nevű fájlból) minden adatot kiolvastunk, az olvasás a másodikon (itt a
szabványos bemeneten) folytatódik tovább.
InputStream in = new SequenceInputStream( (new FileInputStream("papsajt")), System.in );A teljes program: papsajt.java |
Egy Enumeration -be is összegyűjthetünk bemeneti csatornákat,
amelyeket összefűzhetünk egy SequenceInputStream -mé. (A
Vector osztály megvalósítja az Enumeration
interfészt.)
Vector v = new Vector(2); v.addElement(new FileInputStream("papsajt")); v.addElement(System.in); InputStream in = new SequenceInputStream(v.elements());A teljes program: papsajt2.java |
Egy szűrő csatornán keresztül írunk a fout fájlcsatornára
(ami a "vacsora.van" nevű fájlon lett létrehozva).
FileOutputStream fout = new FileOutputStream("vacsora.van"); DataOutputStream dout = new DataOutputStream(fout); dout.writeFloat((float)12.0); // dout-on keresztül fout-ra, azaz a fájlba írA teljes program: vacsora.java |
Az előző példában kiírt adatokat szimmetrikus módon olvassuk vissza,
ismét egy szűrőt használunk.
DataInputStream din = new DataInputStream( new FileInputStream("vacsora.van") ); float f = din.readFloat(); // din-en keresztül a fájlcsatornából olvasA teljes program: vacsora.java |
A szűrőkkel szűrőket is szűrhetünk: a szűrő csatornák egymásba
ágyazhatók, így bizonyos esetekben funkcionalitásuk összeadódik.
FileInputStream fin = new FileInputStream("vacsora.van"); LineNumberInputStream lin = new LineNumberInputStream(fin); DataInputStream din = new DataInputStream(lin); System.out.print(lin.getLineNumber() + ". sor:"); System.out.println(din.readInt()); // beolvasunk négy bájtot System.out.println(lin.read()); // aztán még egy bájtot System.out.println(fin.read()); // és még egyet din.close(); // lezárja mindhárom csatornátA teljes program: beagyazas.java |
Bufferelt beolvasáskor vigyázzunk, hogy ne hívjuk felváltva a szűrt
és a szűrő csatorna olvasó műveleteit, mert így az adatok
összekeveredhetnek, azaz rossz sorrendben kapjuk meg azokat.
BufferedInputStream in = new BufferedInputStream(System.in); System.out.write(in.read()); System.out.write(System.in.read());A teljes program: bufferes.java |
Egy másik példa található bufferelt
beolvasásra a BufferedReader
egy leszármazottjánál,
a LineNumberReader
osztálynál.
A DataOutputStream
használatára a "Szöveges kiírás"
szakaszban láthatunk példát.
Kiírunk 15 bájtot az "okos.txt" nevű fájlba. Először 4, majd 10, végül
1 bájt kerül kiírásra.
FileOutputStream fout = new FileOutputStream("okos.txt"); DataOutputStream dout = new DataOutputStream(fout); PrintStream pout = new PrintStream(fout); dout.writeInt( 1869311859); dout.flush(); pout.print( 1869311859); pout.flush(); fout.write( 1869311859); fout.flush();A teljes program: okos.java |
Egy LineNumberReader objektum segítségével kiírjuk, hogy a
"borok.txt" szövegfájlban mely sorszámú sorok végződnek a "bor"
sztringgel. Egy sor beolvasása a BufferedReader -ből
örökölt readLine metódussal történik.
LineNumberReader be = new LineNumberReader(new FileReader("borok.txt")); String sor; while( (sor = be.readLine()) != null ){ if( sor.endsWith("bor") ) System.out.println(be.getLineNumber()-1); } be.close();A teljes program: borok.java |
A szabványos bemeneti csatorna elején található nulla, egy vagy több
,,fehér szóköz'' karaktert kicseréljük egy darab szóközre.
PushbackReader be = new PushbackReader(new InputStreamReader(System.in),2); int c = be.read(); while( (c == ' ') || (c == '\t') || (c == '\r') || (c == '\n') ) c = be.read(); if( c != -1 ){ // ha nincs vége a csatornának, be.unread(c); // visszatesszük a legutóbbi karaktert, be.unread(' '); // és elé egy szóközt }A teljes program: szokoz.java |
Serializable
interfész
Externalizable
interfész
Ebben a példában, ha egy B típusú objektumot szerializálunk,
az A -ból örökölt x adattag elmentésre kerül, de
ha egy C típusút, akkor nem.
class A implements Serializable { public int x = 42; } class B extends A { private void readObject( ObjectInputStream in ) throws IOException, ClassNotFoundException {} private void writeObject( ObjectOutputStream out ) throws IOException {} } class C extends A implements Externalizable { public C(){ super(); } public void readExternal( ObjectInput in ) throws IOException, ClassNotFoundException {} public void writeExternal( ObjectOutput out ) throws IOException {} }A teljes program: exter.java |
A Dátum osztály három adattagja helyett csak egy számot
tárolunk el, abban lesz (egyértelműen) elkódolva a három adattag
értéke.
class Dátum implements Serializable { int év, hónap, nap; ... private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("dátum", int.class) }; private void writeObject( ObjectOutputStream out ) throws IOException { ObjectOutputStream.PutField adatok = out.putFields(); adatok.put("dátum",10000*év+100*hónap+nap); out.writeFields(); } private void readObject( ObjectInputStream in ) throws IOException, ClassNotFoundException { ObjectInputStream.GetField adatok = in.readFields(); int dátum = adatok.get("dátum",0); nap = (int) (dátum % 100); hónap = (int) ((dátum / 100) % 100); év = (int) (dátum / 10000); } }A teljes program: datum.java |
Ebben a példában az ``adatok.dat'' fájl tartalmát módosítjuk. A fájlban
int típusú értékek vannak. Célunk, hogy minden
háromhatványadik értéket eggyel megnöveljünk. A pozícionálásnál a négyes
szorzókra azért van szükség, mert az int típusú értékek
bináris reprezentációja 4 bájt hosszú.
RandomAccessFile f = new RandomAccessFile("adatok.dat","rw"); int háromhatvány = 1; while( háromhatvány * 4 < f.length() ){ f.seek(háromhatvány * 4); int adat = f.readInt(); f.seek(háromhatvány * 4); f.writeInt(adat+1); háromhatvány *= 3; } f.close();A teljes program: raf.java |
Az alábbi programmal szövegesen tárolt egész számokat tudunk beolvasni.
import java.io.*; class NotExpectedTokenException extends Exception { public int token; public NotExpectedTokenException( int token ){ this.token=token; } } public class TypedReader extends FilterReader { public TypedReader( Reader in ){ super(in); } public int scanInt() throws NotExpectedTokenException, IOException { StreamTokenizer st = new StreamTokenizer(in); st.ordinaryChar('/'); // nincs megjegyzésjel st.ordinaryChar('.'); // ne legyen tizedespont st.nextToken(); if ( (st.ttype==StreamTokenizer.TT_NUMBER) && (st.nval>=Integer.MIN_VALUE) && (st.nval<=Integer.MAX_VALUE) ) return (int)st.nval; // sikerült számként értelmezni else throw new NotExpectedTokenException(st.ttype); } public static void main( String[] args ) throws Exception { TypedReader in = new TypedReader(new InputStreamReader(System.in)); int sum = 0; boolean endOfInts = false; while (!endOfInts) { System.out.print("Írjon be egy számot: "); try{ sum += in.scanInt(); System.out.println(""); }catch (NotExpectedTokenException e){ endOfInts=true; } } System.out.println("\nAz összeg: " + sum); } }A program fájlban: TypedReader.java |
File
-ok: kapcsolat a fájlrendszerrel
File objektumok létrehozása elérési utak megadásával.
File könyvtár = new File("/usr/local/bin"); File ez_is_az = new File("/usr/local","bin"); File fájl = new File(könyvtár,"vim");A teljes program: fajlok.java |
A platformfüggetlen elérési út megadása a File.separator
segítségével történik.
String elv = File.separator; File könyvtár = new File(elv+"usr"+elv+"local"+elv+"bin");A teljes program: fajlok.java |
A "tmp" könyvtárban szereplő "txt" kiterjesztésű fájlokat szeretnénk
kilistázni. Ehhez egy FileFilter |
Készítünk egy olyan jogosultság objektumot, amely a "/tmp/abc.txt"
fájlt, valamint a "read" és a "write" jogokat kapcsolja össze.
FilePermission jog = new FilePermission("/tmp/abc.txt","read,write");A teljes program: abc.java |
Létrehozzuk a "/tmp/abc.txt" fájlt. Ez (alapértelmezést tételezve fel)
sikerül, ha a java abc paranccsal futtatjuk az applikációt,
ha azonban a java -Djava.security.manager abc parancsot
használjuk, java.security.AccessControlException váltódhat
ki.
(new FileOutputStream("/tmp/abc.txt")).close(); // a /tmp/abc.txt létrehozásaA teljes program: abc.java |
A jogosultság meglétét ellenőrizzük. Ha nem rendelkezünk
jog -gal, az előző példához hasonló módon kivétel váltódik
ki.
java.security.AccessController.checkPermission(jog);A teljes program: abc.java |
Az előző két példában kiváltódó kivétel elkerülésére az alábbi szöveget
írhatjuk a user.dir könyvtárunk .java.policy
fájljába.
grant codebase "file:${user.home}/-" { permission java.io.FilePermission "/tmp/abc.txt", "read,write"; };A fájl: java.policy |
java.util.zip
csomag
Ebben a példában egy zip tömörítésű fájlt nyitunk meg,
bontunk ki és tömörítjük vissza gzip fájlokká.
ZipInputStream zin = new ZipInputStream(new FileInputStream("Z.zip")); ZipEntry tag; while( (tag = zin.getNextEntry()) != null ){ if( tag.isDirectory() ){ File név = new File(tag.getName()); név.mkdir(); } else { GZIPOutputStream gzout = new GZIPOutputStream( new FileOutputStream(tag.getName()+".gz") ); int b; while( (b=zin.read()) != -1 ) gzout.write(b); gzout.close(); } } zin.close();A teljes program: tomorit.java |