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ás
A 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át
A 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írni
A 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 ki
A 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 ír
A 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 olvas
A 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át
A 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ása
A 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ések
A 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
|