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.
Megnyitjuk a "hello.txt" szövegfájlt, és kiírunk bele egy sort.
(Láthatóvá kell tennünk a java.io csomag tartalmát,
létre kell hoznunk egy FileWriter objektumot, annak
segítségével pedig egy PrintWriter objektumot. Ezen
utóbbiba tudunk írni a println művelettel. Végül
lezárjuk a csatornát a close metódussal.
import java.io.*; public class HelloVilag_2 { public static void main( String[] args ) throws IOException { PrintWriter out = new PrintWriter( new FileWriter("hello.txt") ); out.println("Helló Világ!"); out.close(); } }A program: HelloVilag_2.java |
Deklarálunk egy csatorna változót, létrehozunk egy csatornát,
majd le is zárjuk a csatornaobjektumot.
FileWriter fout = new FileWriter("nyolcna.a"); // megnyitás char[] c = {'S','z','i','a','!'}; // itt lehet fout.write(c); // írni a fájlba fout.close(); // lezárásA teljes program: megnyit.java |
A flush művelet kikényszeríti, hogy a kiírt adatok
ténylegesen kikerüljenek a fizikai adattárolóra, anélkül, hogy a
csatornát bezárnánk.
byte[] b = {'S','z','i','a','!'}; OutputStream out = socket.getOutputStream(); out.write(b); out.flush(); // továbbra is használhatjuk az out csatornátA teljes program: szokit.java |
Egy kimeneti csatornára kiírjuk egy tömb tartalmát háromféleképpen.
fout.write(tömb); fout.write(tömb,0,tömb.length); for(int i=0; i<tömb.length; i++) fout.write(tömb[i]);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 ) // amíg a csatorna végére nem ér, addig out.write(b); // a beolvasott bájtot kiírja out-ra 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 |
A read műveletek blokkolódnak, ha a bemeneti csatorna üres.
(Véget ért csatornáknál viszont -1 értéket adnak vissza.)
Az is érdekes, hogy a write a beolvasott karaktert írja
ki, a println pedig a kódját. Azaz az első binárisan, a
második szöveges formában írja ki az i változó értékét.
public static void main( String args[] ) throws IOException { int i = System.in.read(); System.out.write(i); System.out.println(" " + i); }A teljes program: ures.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 |
Az available metódus segítségével így kaphatjuk meg
egy fájl méretét:
public static int méret( String fnév ) throws IOException { return (new FileInputStream(fnév)).available(); }A teljes program: fajlmeret.java |
A "masolo.java" forrásfájlt kilistázzuk a képernyőre. Felhasználjuk
az egy korábbi példában már bemutatott
másol metódust.
import java.io.*; public class masolo { public static void main( String[] args ) throws IOException { FileInputStream fin = new FileInputStream("masolo.java"); másol(fin,System.out); fin.close(); } public static void másol( InputStream in, OutputStream out ) throws IOException { ... } }A teljes program: masolo.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 |
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 |
Hozzáférés a ByteArrayOutputStream csatornákra kiírt
adatokhoz:
ByteArrayOutputStream out = new ByteArrayOutputStream(); for( int i=97; i<100; i++ ) out.write(i); out.close(); byte[] b = out.toByteArray(); System.out.write(b); out.writeTo(System.out); String s = out.toString(); System.out.println(s);A teljes program: baos.java |
A StringReader és a StringWriter osztály
használata:
StringWriter out = new StringWriter(10); for( int i=97; i<100; i++ ) out.write(i); out.close(); StringReader in = new StringReader(out.toString()); StringBuffer buf = out.getBuffer();A teljes program: sw.java |
A 336 Unicode kódú karakter az ISO Latin-2 kódtábla
szerint az O" betű. A két bájton ábrázolt Unicode értéket egy bájtra
konvertáljuk (mégpedig a 213 értékre, mert ez az O" betű
kódja az ISO Latin-2 szerint), és ezt a bájtot írjuk ki a
System.out csatornára.
Writer w = new OutputStreamWriter(System.out,"8859_2"); w.write(336); w.flush();A teljes program: latin2.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 |
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. Kiírjuk a 218 Unicode kódú karaktert,
és mire beolvassuk, a 328 Unicode kódú karakter lesz belőle.
PipedInputStream is = new PipedInputStream(); PipedOutputStream os = new PipedOutputStream(is); Reader r = new InputStreamReader(is,"Cp1250"); Writer w = new OutputStreamWriter(os,"MacCentralEurope"); w.write(218); w.flush(); System.out.println(r.read()); // 328-at ír kiA teljes program: kulonbozo.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ást és kiírást alkalmazzunk, ha gyakran kell kis
mennyiségű adatot mozgatni.
Tipikus használat: ha DataInputStream csatornán sok
adatot olvasunk be, pl. readFloat |
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 sort beolvasásni a BufferedReader objektumok
readLine műveletével lehet.
public static void main( String args[] ) throws IOException { BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); System.out.println("Üssön be egy számot: "); String s = r.readLine(); int n = Integer.parseInt(s); System.out.println("A szám négyzete: " + n*n); }A teljes program: sorbe.java |
Egy további példa található bufferelt
beolvasásra a BufferedReader
egy leszármazottjánál,
a LineNumberReader
osztálynál.
Az eddigi példák közül az alábbiak használtak
DataInputStream
vagy DataOutputStream
csatornákat: 1, 2,
3, 4.
A DataOutputStream
használatára a "Szöveges kiírás"
szakaszban láthatunk újabb 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 = adatok.get("dátum",0); nap = (int) (d % 100); hónap = (int) ((d / 100) % 100); év = (int) (d / 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 |
File
osztály: 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 példa ellenőrzi, hogy a "dobj.ki" relatív elérési útvonalú fájlra
a fájlrendszer biztosít-e számunkra írási jogot, és ha igen, akkor
letörli ezt a fájlt.
File törlendő = new File("dobj.ki"); if( törlendő.canWrite() ) törlendő.delete();A teljes program: rm.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 |
Az alábbi program segítségével egy szövegből kiszedegethetjük a
szavakat. Futtassuk például ezt a programot úgy, hogy a
Szavakra.txt fájlt irányítjuk a szabványos
bemenetre: java Szavakra <Szavakra.txt
import java.io.*; class Szavakra { public static void main( String args[] ) throws IOException { StreamTokenizer st = new StreamTokenizer(new InputStreamReader(System.in)); while( st.nextToken() != StreamTokenizer.TT_EOF ) if( st.ttype == StreamTokenizer.TT_WORD ) System.out.println(st.sval); } }A program: Szavakra.java |
Az előző programot kiegészítve az alábbi két sorral a pont írásjeleket
is eltávolíttathatjuk.
st.ordinaryChar(46); // a . legyen közönséges st.slashStarComments(true); // C-szerű megjegyzésekA teljes program: Szavakra2.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 |
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 |
Soronként olvasunk. Feltételezzük, hogy minden sor pontosan egy egész
számot tartalmaz. Ezeket a számokat összeszorozzuk.
import java.io.*; public class Szoroz { public static void main( String args[] ) throws IOException { Reader r = (args.length==0) ? new InputStreamReader(System.in) : new FileReader(args[0]); BufferedReader br = new BufferedReader(r); int szorzat = 1; String szám; while( (szám = br.readLine()) != null ) szorzat *= Integer.parseInt(szám); System.out.println(szorzat); } }A program: Szoroz.java |
Először a szervert indítsuk el, majd a klienst. A kliensnek parancssori
argumentumként megadott szavakat írja ki a szerver. A sztringek a
hálózaton UTF-8 formában utaznak.
import java.io.*; import java.net.*; public class Halozatos { public static void main( String args[] ) throws IOException { Socket so = (new ServerSocket(9999)).accept(); DataInputStream in = new DataInputStream(so.getInputStream()); int db = in.readInt(); for( int i = 0; i < db; i++ ) System.out.println( in.readUTF() ); so.close(); } } class HalozatosKliens { public static void main( String args[] ) throws IOException { Socket so = new Socket("localhost",9999); DataOutputStream out = new DataOutputStream(so.getOutputStream()); out.writeInt(args.length); for( int i = 0; i < args.length; i++ ) out.writeUTF(args[i]); out.close(); } }A program: Halozatos.java |
Az alábbi egyszerű szövegszerkesztő programmal szövegfájlokat tudunk
létrehozni, szerkeszteni, elmenteni és megnyitni.
import java.io.*; import java.awt.*; import java.awt.event.*; public class Sz2 extends Frame { TextArea szöveg = new TextArea(); TextField fájlnév = new TextField(); public Sz2() { addWindowListener( new WindowAdapter(){ public void windowClosing( WindowEvent e ){ setVisible(false); dispose(); System.exit(0); } } ); add(fájlnév,BorderLayout.NORTH); add(szöveg,BorderLayout.CENTER); Panel gombok = new Panel(); add(gombok,BorderLayout.SOUTH); gombok.setLayout(new GridLayout(1,0)); Button betölt = new Button("Betölt"); Button elment = new Button("Elment"); gombok.add(betölt); gombok.add(elment); betölt.addActionListener( new ActionListener(){ public void actionPerformed( ActionEvent ae ){ String sorvége = System.getProperty("line.separator"); try { BufferedReader r = new BufferedReader( new FileReader(fájlnév.getText()) ); szöveg.setText(""); String sor; while( (sor = r.readLine()) != null ) szöveg.append(sor + sorvége); r.close(); } catch (IOException e ) { System.err.println("Hiba beolvasáskor."); } } } ); elment.addActionListener( new ActionListener(){ public void actionPerformed( ActionEvent ae ){ try { PrintWriter w = new PrintWriter(new FileWriter(fájlnév.getText())); w.print(szöveg.getText()); w.close(); } catch (IOException e ) { System.err.println("Hiba kiíráskor."); } } } ); } public static void main( String args[] ){ Sz2 sz = new Sz2(); sz.setSize(400,300); sz.setVisible(true); } }A program: Sz2.java |