Predavanje br. index|1|2|3|4|5|6|7|8|9|10|11|12|13|14|HOME
Operacije ulaza i izlaza - što je stream? – klase streamova
– odakle streamovi dolaze? – klasa InputStream – čitanje byteova – čitanje više
byteova odjednom – prebrojavanje dostupnih byteova – preskakanje byteova –
markiranje i resetiranje – zatvaranje streamova – izlazni streamovi – primjer
izlaznog streama – čitanje iz datoteke primjer čitanja iz datoteke – pisanje u
datoteku – primjer pisanja u datoteku – dodavanje na kraj datoteke – filtriranje
streamova – filtrirani streamovi – bufferirani streamovi – klase podatkovnih
streamova – klasa PrintStream – klasa PushBackInputStream – klasa File –
konstruktori klase File – metode klase File – primjeri metoda iz klase File –
klasa FileDialog – klasa RandomAccessFile – sučelje FilenameFilter – klase
Reader i Writer – klasa Reader – klasa Writer – klasa InputStreamReader – klasa
OutputStreamWriter – dostupne kodne stranice – klasa FileWriter – klasa
FileReader – klasa BufferedReader – klasa LineNumberReader – klasa
BufferedWriter
Podaci se ponekad umjesto na zaslon računala ispisuju u
datoteku. Unix i DOS za tu svrhu imaju redirekcijske operatore <
i >.
Ponekad je potreban i finiji pristup, na primjer ako želite neke podatke uputiti
u datoteku, a druge ostaviti na zaslonu. Ili možda želite istovremeno imati
pristup u više datoteka. Također, možda želite tražiti od korisnika da unese
podatke ne samo preko komandne linije nego i na neki drugi način. Ili želite
pročitati datoteku koja je napisana u određenom formatu, poslati podatke preko
mreže ili ih s nje učitati. U Javi se sve ove operacije obavljaju uz pomoć
streamova. Stream je na primjer i System.out
koji ste susreli već u prvom predavanju.
Stream je niz podataka koji ima neodređenu duljinu. Naziv stream (struja, tok) je odabran jer ta struktura nalikuje struji vode koja neprekidno teče i nema definiranog kraja. Još bolja analogija je rep (red čekanja). Za vrijeme dok se uslužuju ljudi na početku repa, novi dolaze na njegov kraj. Rep je diskretna struktura, ali to ne znači da njegovi članovi nisu međusobno povezani raznim relacijama.
U Javi se stream sastoji od niza diskretnih byteova. Oni mogu predstavljati znakove ili neke druge vrste podataka. Mogu dolaziti brže nego što ih je moguće obraditi ili pak process može čekati dok ne dođe sljedeći za obradu.
Ključ obrade streama je while
petlja
koja obrađuje svaki pojedini element streama dok ne učita znak za kraj streama
ili dok se ne pojavi neki drugi iznimni uvjet. Na Unixu je <Ctrl-D> znak
za završetak streama. Windows za tu svrhu koristi <Ctrl-Z>.
Gotove sve klase koje izravno rade sa streamovima dijelovi su
paketa java.io
.
(Postoji također nekoliko dodatnih u paketima sun.io
i
sun.net
, ali
te su namjerno skrivene. Ima i nekoliko klasa u paketu java.util.zip
.)
Dvije glavne klase su java.io.InputStream
i java.io.OutputStream
.
To su apstraktne klase i one čine temelj mnogih potklasa sa specijaliziranim
mogućnostima. Među njima se najčešće koriste:
BufferedInputStream
BufferedOutputStream
ByteArrayInputStream
ByteArrayOutputStream
DataInputStream
DataOutputStream
FileInputStream
FileOutputStream
FilterInputStream
FilterOutputStream
LineNumberInputStream
ObjectInputStream
ObjectOutputStream
PipedInputStream
PipedOutputStream
PrintStream
PushbackInputStream
SequenceInputStream
StringBufferInputStream
Stream System.out
je, recimo, OutputStream
;
i to posebno, PrintStream
.
Postoji odgovarajući System.in
koji je InputStream
namijenjen čitanju podataka s konzole.
Podaci za streamove dolaze također i iz datoteka. Kasnije ćete vidjeti kako
koristiti klasu File
te klase FileInputStream
i FileOutputStream
za čitanje podataka iz datoteka i pisanje u njih.
Mrežne konekcije obično daju streamove. O tome će biti riječi u zasebnom
predavanju. Kad se povežete na neki web ili ftp ili neki drugi poslužitelj,
čitate podatke koje on šalje tako da s njim povežete jedan InputStream
i jedan OutputStream
.
Java programi i sami proizvode streamove. Na primjer, ByteArrayInputStream
,
ByteArrayOutputStream
,
StringBufferInputStream
,
PipedInputStream
,
i PipedOutputStream
se koriste za prijenos podataka iz jednog dijela Java programa u drugi.
Ponešto neočekivano, komponente kao što je TextArea
ne proizvode streamove. Međutim, stringove koje oni stvaraju uvijek možete
koristiti da biste kreirali ByteArrayInputStream
ili StringBufferInputStream
.
Klasa java.io.InputStream
je apstraktna klasa koja sadrži osnovne metode za čitanje čistih byteova
podataka iz streama. Iako je to apstraktna klasa, mnoge metode u biblioteci
vraćaju objekt tipa InputStream
,
tako da ćete često trebati raditi direktno s nekom od metoda deklariranih u toj
klasi.
public abstract int read() throws IOException
public int read(byte[] data) throws IOException
public int read(byte[] data, int offset, int length) throws IOException
public long skip(long n) throws IOException
public int available() throws IOException
public void close() throws IOException
public synchronized void mark(int readlimit)
public synchronized void reset() throws IOException
public boolean markSupported()
Primijetite
da gotovo sve ove metode mogu izbaciti IOException
.
To vrijedi za uglavnom sve što se odnosi na ulaz i izlaz. Jedina iznimka od tog
pravila je klasa PrintStream
koja će progutati sve iznimke.
Osnovna
read()
metoda iz klase java.io.InputStream
čita pojedinačni neoznačeni byte podataka i vraća njegovu int
vrijednost. To je broj između 0 i 255. Kad se naiđe na kraj streama, vraća se
-1, i to možete koristiti kao flag pomoću kojeg ćete ustanoviti da ste došli do
kraja streama.
public abstract int read() throws IOException
Evo
jednog jednostavnog programa koji vraća kao echo korisnikov unos na komandnoj
liniji. Byte se prije ispisa pretvara u ekvialentni ISO Latin-1 znak. Ovaj
program neće pravilno raditi sa Unicode znakovima. Možete ga dakle koristiti
samo za čiste podatke, a za tekstove i osobito ne-ASCII podatke koristiti klase
java.io.Reader
i java.io.Writer
.
/* Note that as a general rule on most platforms characters
are only sent to System.in a line at a time, not as each character
is typed. This allows the user to backspace over mistakes and
correct them. Java does not allow you to put the console into
"raw" mode. */
import java.io.*;
public class Echo {
public static void main(String[] args) {
echo(System.in);
}
public static void echo(InputStream in) {
try {
while (true) {
// Notice that although a byte is read, an int
// with value between 0 and 255 is returned.
// Then this is converted to an ISO Latin-1 char
// in the same range before being printed.
int i = in.read();
// -1 is returned to indicate the end of stream
if (i == -1) break;
// without the cast a numeric string like "65"
// would be printed instead of the character "A"
char c = (char) i;
System.out.print(c);
}
}
catch (IOException e) {
System.err.println(e);
}
System.out.println();
}
}
% javac Echo.java
% java Echo
abcdefg
abcdefg
<Ctrl-C>
%
Dok
osnovna read()
metoda
čita byte po byte, sljedeće dvije overloaded varijante čitaju polja byteova.
public int read(byte[] data) throws IOException
public int read(byte[] data, int offset, int length) throws IOException
Prva
metoda čita onoliko byteova koliko joj treba da napuni polje data
. Druga
čita onoliko byteova iz ulaznog streama koliko joj je zadano u argumentu
length
i
sprema ih u polje data
počevši
od pozicije offset
.
Te
su metode blokorane dok ne stignu raspoloživi podaci. Tada učitaju onoliko
podataka koliko stane u polje ili koliko je navedeno u length
.
Nakon
toga vraćaju broj byteova koje su učitale. Ne smijete pretpostaviti da će polje
biti uvijek napunjeno ili da će zaista biti učitano length
byteova. Ako naiđe kraj streama, vraća se -1.
Metoda
available()
ispituju koliko byteova sa uzlaznog streama je spremno za učitavanje bez
blokiranja.
public int available()
throws IOException
Na
primjer, sljedeći program je efikasnija verzija prethodnog programa Echo
jer
koristi metodu available()
za
ispitivanje koliko byteova je spremno za učitavanje, a zatim kreira polje točno
te veličine, učitava byteove u polje i konvertira ga u String
koji
zatim ispisuje.
import java.io.*;
public class EfficientEcho {
public static void main(String[] args) {
echo(System.in);
}
public static void echo(InputStream in) {
try {
while (true) {
int n = in.available();
if (n > 0) {
byte[] b = new byte[n];
int result = in.read(b);
if (result == -1) break;
String s = new String(b);
System.out.print(s);
} // end if
} // end while
} // end try
catch (IOException e) {
System.err.println(e);
}
}
}
% javac Echo.java
% java Echo
abcdefg
abcdefg
<Ctrl-C>
%
Metoda
skip()
čita i odbacuje specificirani broj byteova.
public int skip(long n)
throws IOException
Možete
je koristiti, na primjer, ako želite brzo prođi standardni header ili prefiks
nekih podataka. U sljedećem fragmentu koda koristi se skip()
za
preskakanje praznina uključenih u DataInputStream
dis.
case 171: // lookupswitch
pad = 3 - (position % 4);
dis.skip(pad);
defaultByte = dis.readInt();
int npairs = dis.readInt();
result = position + " lookupswitch " + defaultByte + " " + npairs;
for (int i = 0; i < npairs; i++) {
int newPosition = position + pad + 12 + i*8;
result += "\n" + newPosition + " "
+ dis.readInt() + " " + dis.readInt();
}
Često je korisno ako možete učitati nekoliko byteova, a zatim se vratiti natrag i učitati ih ponovo. Na primjer, pri oblikovanju nekog kompajlera ne možete znati da li trebate učitati znak <, <<, ili <<= sve dok ne učitate dva ili više byteova. Bilo bi korisno ako biste se mobli vratiti natrag i ponovo učitati token nakon što ste okrili o kojem se radi. Dizajniranje kompajlera i problemi parsiranja uvijek osiguravaju mnoštvo primjera, no slične potrebe se pojavljuju i drugdje.
Neki, ali ne svi streamovi dopuštaju vam da markirate određenu poziciju u streamu i onda se vratite na nju. To se radi pomoću sljedećih metoda:
public synchronized void mark(int readlimit)
public synchronized void reset() throws IOException
public boolean markSupported()
Metoda
markSupported()
vraća true
ako taj
stream podržava markiranje, a false
inače.
Pod
pretpostavkom da je markiranje podržano, metoda mark()
stavlja bookmark na mjesto gdje se kasnije želite vratiti pomoću metode
reset()
.
Istodobno u jednom streamu može postojati samo jedan takav bookmark. Sljedeće
markiranje izbrisat će prethodno. Ako markiranje nije podržano, ove će metode
izbaciti IOException
.
Kad
ste završili s nekim streamom, trebali biste ga zatvoriti kako bi se otpustili
resursi koji su s njim povezani. Jednom kad je stream zatvoren, svaki pokušaj
čitanja iz njega izbacit će IOException
.
Stream
(u ovom slučaju ulazni) zatvarate pomoću metode close()
:
public void close() throws
IOException
Ako
se stream ne može zatvoriti, izbacit će se IOException
.
Klasa
java.io.OutputStream
šalje čiste byteove podataka na neko odredište, npr. konzolu ili mrežni
poslužitelj. Ova je klasa apstraktna, isto kao i InputStream
.
Međutim, mnoge metode u biblioteci klasa napravljene su tako da vraćaju objekte
tipa OutputStream
umjesto objekte iz njenih specifičnih podklasa. Također, mnoge metode klase
OutputStream
su općenito korisne. To su:
public abstract void write(int b) throws IOException
public void write(byte[] data) throws IOException
public void write(byte[] data, int offset, int length) throws IOException
public void flush() throws IOException
public void close() throws IOException
Nekoliko
različitih write()
metoda šalju čiste byteove podataka svakom procesu koji osluškuje dani stream.
Ponekad
operacijski sustav bufferira izlazne streamove zbog boljih performansi. To znači
da se byteovi prije ispisa akumuliraju u spremnik čija veličina može biti od
nekoliko byteova do nekoliko tisuća byteova. Kad se on napuni, svi podaci se
ispisuju odjednom. Metoda flush()
pokrenut će, međutim, ispis bez obzira da li je spremnik pun ili nije.
Primijetite
da to nije isto što i bufferiranje koje provodi klasa BufferedOutputStream
koje izvodi Java runtime. Ovdje se radi o native bufferiranju,
dakle procesu na razini operacijskog sustava. Međutim, poziv metode flush()
trebao
bi isprazniti oba spremnika.
Metoda
close()
zatvara stream i otpušta resurse koji su s njim povezani. Jednom kad je stream
zatvoren, pokušaj pisanja u njega izbacit će IOException
.
Jedini
izlazni streamovi koje ste do sad upoznali su System.out
i System.err
.
Sljedeći primjer koristi metode write()
and flush()
iz klase OutputStream
da bi na System.out
ispisao string “Hello World”
import java.io.*;
public class HelloOutputStream {
public static void main(String[] args) {
String s = "Hello World\r\n";
// Convert s to a byte array
byte[] b = new byte[s.length()];
s.getBytes(0, s.length()-1, b, 0);
try {
System.out.write(b);
System.out.flush();
}
catch (IOException e) {
System.err.println(e);
}
}
}
% javac HelloOutputStream.java
% java HelloOutputStream
ello World
%
Primijetite da program ne radi baš onako kako bi se očekivalo nego proguta prvi znak.
Klasa
java.io.FileInputStream
predstavlja InputStream
koji čita byteove iz datoteke. Ima sljedeće public konstruktore i metode:
public FileInputStream(String name) throws FileNotFoundException
public FileInputStream(File file) throws FileNotFoundException
public FileInputStream(FileDescriptor fdObj)
public native int read() throws IOException
public int read(byte[] data) throws IOException
public int read(byte[] data, int offset, int length) throws IOException
public native long skip(long n) throws IOException
public native int available() throws IOException
public native void close() throws IOException
public final FileDescriptor getFD() throws IOException
S
iznimkom konstruktora te metode getFD()
,
ove metode samo prekrivaju istoimene metode klase java.io.InputStream
.
Jedina je razlika što čitaju podatke iz datoteke.
Novi
objekt tipa FileInputStream
konstruirate tako da konstruktoru proslijedite ime datoteke, na primjer:
FileInputStream fis = new
FileInputStream("ulaz.txt");
Ako
datoteka ne postoji, izbacit će se iznimka FileNotFoundException
,
podklasa od IOException
.
Općenito, Java će tražiti datoteke u aktivnom direktoriju, no one se ne moraju
nužno nalaziti u direktoriju u kojem se nalazi .class datoteka.
Sljedeća
aplikacija čita datoteke koje su navedene na komandnoj liniji i ispisuje njihov
sadržaj na System.out
.
import java.io.*;
public class Type {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
try {
FileInputStream fis = new FileInputStream(args[i]);
int n;
while ((n = fis.available()) > 0) {
byte[] b = new byte[n];
int result = fis.read(b);
if (result == -1) break;
String s = new String(b);
System.out.print(s);
} // end while
fis.close();
} // end try
// Is this catch strictly necessary?
catch (FileNotFoundException e) {
System.err.println("Could not find file " + args[i]);
}
catch (IOException e) {
System.err.println(e);
}
System.out.println();
} // end for
} // end main
}
% javac Type.java
% java Type "../html/TricksterApplet.html"
<APPLET CODE="TricksterApplet.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="Trickster.jar"
WIDTH=1 HEIGHT=1>
</APPLET>
%
Klasa
java.io.FileOutputStream
predstavlja OutputStream
koji upisuje byteove u datoteku. Ima sljedeće public konstruktore i metode:
public FileOutputStream(String name) throws IOException
public FileOutputStream(String name, boolean append) throws IOException
public FileOutputStream(File file) throws IOException
public FileOutputStream(FileDescriptor fdObj)
public native void write(int b) throws IOException
public void write(byte[] data) throws IOException
public void write(byte[] data, int offset, int length) throws IOException
public native void close() throws IOException
public final FileDescriptor getFD() throws IOException
S
iznimkom konstruktora te metode getFD()
,ove
metode samo prekrivaju istoimene metode klase java.io.OutputStream
.
Jedina je razlika što pišu podatke u datoteku.
Novi
objekt tipa FileOutputStream
konstruirate tako da konstruktoru proslijedite ime datoteke, na primjer:
FileOutputStream fos = new
FileOutputStream("izlaz.txt");
Ako datoteka postoji u aktivnom direktoriju, bit će prebrisana i u nju upisani novi podaci. Ako ne postoji, kreirat će se.
U
sljedećem primjeru čita se korisnikov input sa System.in
i ispisuje se u datoteke specificirane na komandnoj liniji.
import java.io.*;
public class MultiType {
public static void main(String[] args) {
FileOutputStream[] fos = new FileOutputStream[args.length];
for (int i = 0; i < args.length; i++) {
try {
fos[i] = new FileOutputStream(args[i]);
}
catch (IOException e) {
System.err.println(e);
}
} // end for
try {
while (true) {
int n = System.in.available();
if (n > 0) {
byte[] b = new byte[n];
int result = System.in.read(b);
if (result == -1) break;
for (int i = 0; i < args.length; i++) {
try {
fos[i].write(b, 0, result);
}
catch (IOException e) {
System.err.println(e);
}
} // end for
} // end if
} // end while
} // end try
catch (IOException e) {
System.err.println(e);
}
for (int i = 0; i < args.length; i++) {
try {
fos[i].close();
}
catch (IOException e) {
System.err.println(e);
}
}
} // end main
}
% javac MultiType.java
% java MultiType izlaz1.txt izlaz2.txt
nebo je plavo
<Ctrl-C>
%
% ls izlaz*.txt
izlaz1.txt
izlaz2.txt
% more izlaz1.txt
nebo je plavo
% more izlaz2.txt
nebo je plavo
%
Ako
želite da se novi sadržaj doda na kraj datoteke umjesto da prebriše prethodni
sadržaj, proslijedit ćete vrijednost true
kao drugi
argument konstruktoru FileOutputStream()
.
Na primjer:
FileOutputStream fos = new
FileOutputStream("izlaz.txt", true);
U
sljedećem primjeru čita se korisnikov input sa System.in
i dodaje na kraj datoteka specificiranih na komandnoj liniji.
import java.io.*;
public class Append {
public static void main(String[] args) {
FileOutputStream[] fos = new FileOutputStream[args.length];
for (int i = 0; i < args.length; i++) {
try {
fos[i] = new FileOutputStream(args[i], true);
}
catch (IOException e) {
System.err.println(e);
}
} // end for
try {
while (true) {
int n = System.in.available();
if (n > 0) {
byte[] b = new byte[n];
int result = System.in.read(b);
if (result == -1) break;
for (int i = 0; i < args.length; i++) {
try {
fos[i].write(b, 0, result);
}
catch (IOException e) {
System.err.println(e);
}
} // end for
} // end if
} // end while
} // end try
catch (IOException e) {
System.err.println(e);
}
for (int i = 0; i < args.length; i++) {
try {
fos[i].close();
}
catch (IOException e) {
System.err.println(e);
}
} // end for
} // end main
}
% javac Append.java
% java Append izlaz1.txt izlaz2.txt
a trava je zelena.
<Ctrl-C>
% more izlaz1.txt
nebo je plavo
a trava je zelena.
% more izlaz2.txt
nebo je plavo
a trava je zelena.
%
Klase
java.io.FilterInputStream
i java.io.FilterOutputStream
su konkretne podklase od InputStream
i OutputStream
koje na neki način modificiraju podatke osnovnih streamova. Rijetko ćete ih
koristiti izravno, ali njihove su podklase iznimno važne, posebno DataInputStream
i DataOutputStream
.
Filtar-stream
povezujete s osnovnim tako da da osnovni proslijedite konstruktoru
filtar-streama. Na primjer, da biste kreirali novi objekt tipa DataOutputStream
iz objekta FileOutputStream
mogli biste postupiti ovako:
FileOutputStream fos = new FileOutputStream("ln.txt");
DataOutputStream dos = new DataOutputStream(fos);
To se može kombinirati i u jednoj liniji:
DataOutputStream dos = new DataOutputStream(new FileOutputStream("ln.txt"));
BufferedInputStream
i BufferedOutputStream
Ove klase bufferiraju čitanje i pisanje tako da podatke najprije učitavaju u spremnik (buffer, interrno polje byteova). Tako neka aplikacija može čitati byteove iz streama bez pozivanja native metoda koje iza toga stoje. Podaci se učitavaju iz buffera ili u njega upisuju u blokovima, a naknadni pristupi usmjeravaju se direktno prema spremniku.
DataInputStream
i DataOutputStream
Ove klase čitaju i pišu podatke koji pripadaju primitivnim Java tipovima, kao i podatke tipa String na način koji ne ovisi o mašini (Big-endian za integer, IEEE-754 za float i double, UTF-8 za Unicode)
Ova ste klasu već susretali preko njenih implementacija System.out i System.err. Omogućuje vrlo jednostavno ispisivanje primitivnih vrijednosti, objekata i string literala. Klasa hvata sve iznimke tipa IOException i namijenjena je ponajprije za debugging.
Ova klasa osigurava pushback spremnik pomoću kojeg je moguće "poništiti" čitanje byteova sa streama. Kod sljedećeg čitanja sa streama bit će učitani ti “poništeni” byteovi.
GZIPInputStream
i GZIPOutputStream
Ovo
su klase iz paketa java.util.zip
i obavljaju kompresiju i dekompresiju podataka.
DigestInputStream
i DigestOutputStream
Ovo
su klase iz paketa java.security
i izračunavaju tzv. MessageDigest
za streamove koristeći neku jaku hash funkciju, npr SHA.
CipherInputStream
i CipherOutputStream
Klase
su iz paketa javax.crypto
koji je dio Java Cryptography
Extension (JCE), standardnog proširenja Jave, a uključen je u
JavaTM 2 Platform Std. Ed. v1.4.0. i izračunavaju enkripcije i dekripcije
streamova koristeći razne algoritme kao DES, RSA, Blowfish i druge.
ObjectInputStream
i ObjectOutputStream
Podklase
od of DataInputStream
i DataOutputStream
koje mogu serijalizirati i deserijalizirati Java objekte u čiste byteove (i
obratno). Koristi se kod udaljenog pozivanja metoda (RMI) i za JavaBeans.
Možete
kreirati i svoje vlastite podklase od java.io.FilterInputStream
i java.io.FilterOutputStream
koje će izvoditi filtriranja prema vašim potrebama.
Klase
java.io.BufferedInputStream
i java.io.BufferedOutputStream
omogućuju čitanje i pisanje na način da se podaci prvo spremaju u spremnik
(buffer) koji je zapravo interno polje byteova. Program tada čita byteove iz
streama bez prethodnog pozivanja native metode dok god ima podataka u
spremniku. Podaci se čitaju iz spremnika ili pišu u njega u blokovima, a nakon
toga su dostupni izravno iz spremnika.
Sa stanovišta programera, jedina razlika između običnog i bufferiranog streama je u konstruktorima:
public BufferedInputStream(InputStream in)
public BufferedInputStream(InputStream in, int size)
public BufferedOutputStream(OutputStream out)
public BufferedOutputStream(OutputStream out, int size)
Argument
size
je broj
byteova u spremniku. Ako nije naveden, podrazumijeva se 512.
Optimalna veličina spremnika jako ovisi o platformi i općenito je povezana sa veličinom bloka na disku, barem za datotečne streamove. Manje od 512 će vjerojatno biti premalo, a više od 4096 previše. Idealno bi bilo da veličina spremnika bude cjelobrojni višekratnik veličine bloka diska. Za nepouzdane mrežne konekcije bolje je odabrati manju veličinu spremnika. Na primjer,
URL u = new URL("http://java.developer.com");
BufferedInputStream bis = new BufferedInputStream(u.openStream(), 256);
Klase
java.io.DataInputStream
i java.io.DataOutputStream
čitaju i pišu primitivne Java tipove podataka i stringove na način koji ne ovisi
o mašini. Općenito ćete DataInputStream
koristiti za čitanje podataka koji su napisani pomoću DataOutputStream
.
Taj format koristi standard IEEE 754 za floating point, big-endian za integer, i
modificirani UTF-8 za Unicode.
DataOutputStream
deklarira sljedeće konstruktore i metode:
public DataOutputStream(OutputStream out)
public synchronized void write(int b) throws IOException
public synchronized void write(byte[] data, int offset, int length) throws IOException
public final void writeBoolean(boolean b) throws IOException
public final void writeByte(int b) throws IOException
public final void writeShort(int s) throws IOException
public final void writeChar(int c) throws IOException
public final void writeInt(int i) throws IOException
public final void writeFloat(float f) throws IOException
public final void writeDouble(double d) throws IOException
public final void writeBytes(String s) throws IOException
public final void writeChars(String s) throws IOException
public final void writeUTF(String s) throws IOException
public final int size()
public void flush() throws IOException
Metoda
size()
vraća broj byteova koji su ispisani na izlazni stream.
Klasa
java.io.PrintStream
je podklasa od FilterOutputStream
.
Implementirana je u System.out
i System.err
.
Omogućuje jednostavan ispis primitivnih vrijednosti, objekata i string literala.
Za konvertiranje znakova u byteove koristi kodiranje koje je na danoj platformi
default.
Ta
klasa će uhvatiti sve iznimke tipa IOException
,
Status pogreške možete uvijek doznati pomoću metode checkError()
.
Ona će vratiti true
ako se
greška pojavila, false
inače.
public boolean
checkError()
Ono
što se najviše koristi u ovoj klasi su (overlodaded) metode print()
i
println()
.
Metode println()
dodaju znak za završetak linije svemu što ispisuju, za razliku od metoda
print()
koje
to ne čine.
public void print(boolean b)
public void print(int i)
public void print(long l)
public void print(float f)
public void print(double d)
public void print(char s[])
public void print(String s)
public void print(Object obj)
public void println()
public void println(boolean x)
public void println(char x)
public void println(int x)
public void println(long x)
public void println(float x)
public void println(double x)
public void println(char x[])
public void println(String x)
public void println(Object x)
Klasa
PrintStream
je uglavnom namijenjena debagiranju programa. Inače je neslužbeno deprecated u
Javi 1.1. i dalje. Umjesto nje ćete više koristiti klasu PrintWriter
.
Klasa
PushbackInputStream
osigurava pushback spremnik pomoću kojeg je moguće "poništiti" čitanje
byteova sa streama. Kod sljedećeg čitanja sa streama bit će učitani ti
“poništeni” byteovi.
public void unread(int b) throws IOException
public void unread(byte[] data, int offset, int length) throws IOException
public void unread(byte[] data) throws IOException
Po
pretpostavci, spremnik ima veličinu od jednog bytea pa će pokušaj poništavanja
više byteova izbaciti IOException
.
No veličinu spremnika možete zadati ako uporabite drugi od sljedeća dva
konstruktora.
public PushbackInputStream(InputStream in)
public PushbackInputStream(InputStream in, int size)
Iako
i PushbackInputStream
i BufferedInputStream
koriste spremnike, jedino PushbackInputStream
dopušta poništavanje, a jedino BufferedInputStream
dopušta markiranje i resetiranje. Za streamove tipa PushbackInputStream
metoda markSupported()
vraća false.
public boolean markSupported()
Metode
read()
i available()
rade jednako kao s običnim ulaznim streamovima, jedino što najprije pokušavaju
čitati iz pushback spremnika.
public int read() throws IOException
public int read(byte[] data, int offset, int length) throws IOException
public int available() throws IOException
Klasa
java.io.File
predstavlja eksterno ime datoteke na računalu. Njome se pokušavaju apstrahirati
dijelovi imena koji su zavisni o računalu, na primjer put, separator i slično.
Dva su načina referenciranja datoteka, relativni i apsolutni. Apsolutno imenovanje daje potpuni put do datoteke, počevši od imena diska pa dalje. Detalji ovise o operacijskom sustavu. Na primjer:
Unix: "/math/vedris/file1"
DOS: "C:\math\vedrisfile1"
MacOS: "Macintosh HD:math:vedris:file1"
Sva ova tri stringa referenciraju datoteku file1 na glavnom disku u direktoriju /math/vedris/. Razlikuju se na primjer po separatoru. Unix koristi /, Dos i Windows \, MacOS :. Drugi sustavi mogu koristiti nešto posve drugo.
Također, nema garancije da se glavni disk na Macu zove baš “Macintosh HD” ili da uopće postoji disk s tim imenom. Na Unixu “/” i “/math” moggu biti na različitim diskovima, pa čak i na različitim mašinama. Zbog takvih razloga apsolutna imena treba uglavnom izbjegavati.
Relativno imenovanje koje treba koristiti kad god je moguće, ne daje potpuni put do datoteke. Umjesto toga daje put koji je relativan prema nekoj poznatoj datoteci. Relativni put može pokazivati datoteku u istom direktoriju u kojem se nalazi poznata datoteka jednostavno navođenjem njenog imena. Ili može pokazivati na datoteku u poddirektoriju poznatog direktorija.
Općenito se jedan direktorij uzima za “radni” i metode koje traže datoteke činit će to u odnosu na taj direktorij. Uobičajeno je da to bude direktorij iz kojeg započinjete izvršavati aplikaciju.
Objekt
tipa java.io.File
može biti ime direktorija isto kao i ime datoteke.
Primijetite
da objekt tipa File
nije isto što i file handle. Postojanje takvog objekta nije ekvivalentno
postojanju stvarne datoteke na disku. Postoje metode kojima možete utvrditi da
li dani File
objekt zaista referencira stvarnu datoteku ili ne (metoda exists()
).
Tri
su konstruktora za klasu File
.
Svaki uzima neku varijaciju imena datoteke kao argument. Najjednostavniji je
public File(String path)
Ovdje
je path
naprosto
String
koji
sadrži potpuni ili relativni put do datoteke, napisan na isti način kao za
operacijski sustav računala. Na primjer:
File f1 = new File("ulaz.txt");
File f2 = new File("/etc/passwd");
Ako želite, možete put do datoteke odvojiti od njenog imena koristeći sljedeći konstruktor:
public File(String path, String name)
Ovdje
je name
ime
datoteke, a path
ime
direktorija u kojem se ona nalazi. Na primjer:
File f2 = new File("/etc", "passwd");
Na kraju, imamo i konstruktor
public File(File dir, String name)
koji
se ponaša kao i prethodni, ali je dir
ovdje
objekt tipa File
,
a ne naprosto String
.
Neke
metode u drugim klasama također vraćaju objekt tipa File
,
na primjer metode iz klase java.awt.FileDialog
.
Takvi će objekti poštovati sve konvencije operacijskog sustava na kojem se
aplikacija izvršava.
Kad
jednom imate objekt tipa File
,
postoji mnogo stvari koje o njemu možete pitati i koje s njim možete učiniti.
public String
getName()
Elementarno
pitanje o datoteci je ono o njenom imenu. Ime ćete doznati pomoću metode
getName()
koja ne uzima nikakve argumente, a vraća String
koji
sadrži eksterno ime datoteke (bez puta). Na primjer, dobit ćete "file1"
umjesto "/math/vedris/file1"
.
public String
getPath()
Metoda
getPath()
vraća a String
koji
sadrži put do datoteke. Bit će relativan ili apsolutan, ovisno o načinu na koji
je dani objekt bio kreiran.
public String
getAbsolutePath()
Metoda
getAbsolutePath()
vraća puni, apsolutni put do datoteke.
public String
getCanonicalPath() throws IOException
Metoda
getCanonicalPath()
vraća kanonsku formu puta do datoteke. Ta je forma zavisna o operacijskom
sustavu i mašini.
public String
getParent()
Metoda
getParent()
vraća String
koji
sadrži ime jedinstvenog nadređenog direktorija u odnosu na onaj u kojem se
datoteka nalazi, ili null
ako je
već dosegnut vrh hijerarhije.
public boolean exists()
throws SecurityException
Metoda
exists()
naznačuje da li određena datoteka postoji na mjestu gdje je očekujete.
public boolean canWrite()
throws SecurityException
Metoda
canWrite()
daje odgovor da li imate pravo pisanja u datoteku. To nije loše provjeriti prije
nego stvarno pokušati nešto upisati.
public boolean canRead()
throws SecurityException
Metoda
canRead()
daje odgovor da li imate pravo čitanja iz datoteke. Dobro ju je koristiti prije
stvarnog pokušaja čitanja.
public boolean isFile()
throws SecurityException
Metoda
isFile()
odgovara na pitanje da li se radi o datoteci (za razliku od direktorija).
public boolean isDirectory()
throws SecurityException
Metoda
isDirectory()
vraća true
ako se
radi o (postojećem) direktoriju.
public boolean
isAbsolute()
Metoda
isAbsolute()
vraća true
ako je
dano ime apslolutni put, a false
ako
nije.
public long lastModified()
throws SecurityException
Metoda
lastModified()
vraća vrijeme zadnje promjene. Kako je konverzija u pravi datum dugačka, a
procedura ovisna o platformi, to treba koristiti uglavnom za usporedbu vremena
zadnje promjene dvaju različitih datoteka.
public long length() throws
SecurityException
Metoda
length()
daje veličinu datoteke u byteovima.
public boolean
mkdir()
Metoda
mkdir()
pokušava kreirati direktorij sa zadanim imenom. Ako uspije, vratit će
true
, inače
false
.
public boolean mkdirs()
throws SecurityException
Metoda
mkdirs()
za dano ime kreira ne samo jedan, nego sve potrebne nadređene direktorije koji
čine put do datoteke. Ako sva kreiranja uspiju, vratit će se true
, inače
false
(čak ako
su neka kreiranja i uspjela).
public boolean renameTo(File
destination) throws SecurityException
Metoda
renameTo()
pokušava preimenovati datoteku. Na primjer, f1.renameTo(f2)
pokušava preimenovati f1
u f2.
To može značiti i premiještanje u drugi direktorij ako imena tako naznačuju. Ako
f2 već postoji, bit će prebrisana sa f1 (pod uvjetom da imate odgovarajuće
dozvole). Ako preimenovanje uspije, vraća se true
, inače
false
.
public String[] list()
throws SecurityException
Metoda
list()
vraća polje stringova koji sadrže imena datoteka u navedenom direktoriju.
Korisna je za procesiranje svih datoteka unutar direktorija odjednom.
public String[]
list(FilenameFilter filter) throws SecurityException
Ova varijanta metode list() čini isto što i prethodna, ali možete koristiti objekt klase koja implementira sučelje FilenameFilter (pogledajte poglavlje o tome) za filtriranje imena datoteka.
public boolean delete()
throws SecurityException
Metoda
delete()
pokušava izbrisati datoteku na koju se odnosi. Vraća true
ako je
datoteka postojala i sad je izbrisana, inače false
.
Klasa
File
sadrži i uobičajene metode equals()
,
hashCode()
i toString()
koje se ponašaju točno onako kao što biste očekivali. Ne sadrži posebnu metodu
clone()
.
Sljedeći
program čita imena datoteka s komandne linije i vraća razne informacije o njima,
koristeći metode iz klase File
.
import java.io.*;
public class FileInfo {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
File f = new File(args[i]);
if (f.exists()) {
System.out.println("getName: " +
f.getName());
System.out.println("getPath: " +
f.getPath());
System.out.println("getAbsolutePath: " +
f.getAbsolutePath());
try {
System.out.println("getCanonicalPath: " +
f.getCanonicalPath());
}
catch (IOException e) {
}
System.out.println("getParent: " +
f.getParent());
if (
f.canWrite()) System.out.println(f.getName() + " is writable.");
if (
f.canRead()) System.out.println(f.getName() + " is readable.");
if (
f.isFile()) {
System.out.println(f.getName() + " is a file.");
}
else if (
f.isDirectory()) {
System.out.println(f.getName() + " is a directory.");
}
else {
System.out.println("What is this?");
}
if (
f.isAbsolute()) {
System.out.println(f.getName() + " is an absolute path.");
}
else {
System.out.println(f.getName() + " is not an absolute path.");
}
System.out.println("Last Modified" +
f.lastModified());
System.out.println(f.getName() + " is " +
f.length() + " bytes.");
}
else {
System.out.println("I'm sorry. I can't find the file " + args[i]);
}
}
}
}
% javac FileInfo.java
% java FileInfo "../html/TricksterApplet.html"
getName: TricksterApplet.html
getPath: ../html/TricksterApplet.html
getAbsolutePath: /math/vedris/public_html/java/classes/../html/TricksterApplet.html
getCanonicalPath: /math/vedris/public_html/java/html/TricksterApplet.html
getParent: ../html
TricksterApplet.html is writable.
TricksterApplet.html is readable.
TricksterApplet.html is a file.
TricksterApplet.html is not an absolute path.
Last Modified1005656988000
TricksterApplet.html is 151 bytes.
%
Klasa
java.awt.FileDialog
je podklasa od java.awt.Dialog
koja se koristi za otvaranje ili spremanje datoteka. Ona koristi standardne
dijaloge za open i save koji već postoje na računalu. Ne dodajete
joj komponente i ne brinete se o tome kako je implementirana interakcija s
korisnikom. Jednostavno dobijete rezultat koji će biti ime i direktorij
datoteke. Budući da se appleti ne mogu osloniti na to da imaju dostup u file
system, ova je klasa korisna uglavnom u aplikacijama.
Tri su koraka potrebna da biste koristili FileDialog:
FileDialog
FileDialog
vidljivim.
Novi objekt tipa FileDialog kreirate pomoću konstruktora:
public FileDialog(Frame parent, String title, int mode)
Okvir
Frame
je roditelj dijaloga. To će obično biti glavni prozor aplikacije, appletov okvir
ili najistaknutiji prozor aplikacije. Također možete naprosto krerirati i novi
Frame
.
Argument title
je
naslov za naš FileDialog,
obično nešto kao "Please choose the file to open:" Nadaljue, mode
je jedna
od dvije mnemoničkih konstanti, FileDialog.LOAD
ili FileDialog.SAVE
.
Prvu ćete koristiti ako želite da korisnik odabere datoteku koju će otvoriti, a
drugu ako želite da odabere datoteku u koju će spremiti podatke. Tipičan primjer
izgledao bi ovako:
FileDialog fd = new FileDialog(new Frame(), "Please choose a file:", FileDialog.LOAD);
Konačno,
učinit ćete FileDialog
vidljivim na isti način kao i druge komponente. Proslijedit ćete true
njegovoj
metodi setVisible()
koju je naslijedio iz klase java.awt.Component.
fd.setVisible(true);
Odavde
na dalje operacijski sustav preuzima kontrolu nad interakcijom s korisnikom sve
dok on ne odabere datoteku ili izađe iz dijaloga. Vaš program će ovdje stati i
čekati da korisnik odabere datoteku. Kad on to učini, dijalog će nestati s
ekrana i vaš program će se nastaviti. Tada ćete ustanoviti što je korisnik
odabrao, tako da pozovete metode getDirectory()
i getFile()
.
Iskoristite ova dva stringa da biste kreirali novi objekt tipa File
.
Ukratko,
FileDialog fd = new FileDialog(new Frame(), "Please choose a file:", FileDialog.LOAD);
fd.show();
if (fd.getFile() != null) {
File f = new File(fd.getDirectory(), fd.getFile());
}
Ako
korisnik otkaže spremanje, obje metode, getDirectory()
i getFile()
vraćaju null. Budite sigurni da ste provjerili tu mogućnost.
Pomoću klase java.io.RandomAccessFile pristupa se datotekama koje podržavaju slučajni pristup. One se mogu čitati ili se u njih može pisati počevši od određene pozicije bytea u datoteci. Tu poziciju specificira pokazivač datoteke (file pointer).
Dva su konstruktora u ovoj klasi:
public RandomAccessFile(String name, String mode) throws IOException
public RandomAccessFile(File file, String mode) throws IOException
Prvi argument je datoteka kojoj želite pristupiti. Drugi je način pristupa. To može biti string "r" za read-only ili "rw" za pristup koji omogućuje čitanje i pisanje. Java ne podržava write only pristup. Na primjer,
RandomAccessFile raf = new RandomAccessFile("ulaz.txt", "r");
Metode
getFilePointer()
,
length()
,
i seek()
omogućuju vam da utvrdite i modificirate poziciju u datoteci na kojoj se čitanje
i pisanje događa. Pokušaj traženja pozicije iza kraja datoteke pomaknut će
pointer na kraj. Pokušaj pisanja na kraj datoteke proširit će datoteku, a
pokušaj čitanja s kraja datoteke izbacit će EOFException
.
public native long getFilePointer() throws IOException
public native void seek(long pos) throws IOException
public native long length() throws IOException
Za
čitanje i pisanje koriste se metode koje rade identično kao i metode iz
DataInputStream
i DataOutputStream
,
osim što između poziva metoda za čitanje i pisanje možete zadati poziciju od
koje čitate ili pišete.
public native int read() throws IOException
public int read(byte[] input, int offset, int length) throws IOException
public int read(byte[] input) throws IOException
public final void readFully(byte[] input) throws IOException
public final void readFully(byte[] input, int offset, int length) throws IOException
public native void write(int b) throws IOException
public void write(byte[] data) throws IOException
public void write(byte[] data, int offset, int length) throws IOException
public final boolean readBoolean() throws IOException
public final byte readByte() throws IOException
public final int readUnsignedByte() throws IOException
public final short readShort() throws IOException
public final int readUnsignedShort() throws IOException
public final char readChar() throws IOException
public final int readInt() throws IOException
public final long readLong() throws IOException
public final float readFloat() throws IOException
public final double readDouble() throws IOException
public final String readLine() throws IOException
public final String readUTF() throws IOException
public final void writeBoolean(boolean b) throws IOException
public final void writeByte(int b) throws IOException
public final void writeShort(int s) throws IOException
public final void writeChar(int c) throws IOException
public final void writeInt(int i) throws IOException
public final void writeLong(long l) throws IOException
public final void writeFloat(float f) throws IOException
public final void writeDouble(double d) throws IOException
public final void writeBytes(String s) throws IOException
public final void writeChars(String s) throws IOException
public final void writeUTF(String s) throws IOException
Konačno, ima još nekoliko raznih metoda:
public final FileDescriptor getFD() throws IOException
public int skipBytes(int n) throws IOException
public native void close() throws IOException
Sučelje
java.io.FilenameFilter
deklarira sljedeću metodu:
public boolean accept(File
directory, String filename)
Ona
treba vraćati true
ako
datoteka prolazi kroz filtar, false
inače.
Budući
da je FilenameFilter
sučelje, morate ga implementirati u nekoj klasi. Ovdje je primjer klase koja
filtrira sve što nije java source datoteka.
import java.io.*;
public class JavaFilter
implements FilenameFilter {
public boolean
accept(File directory, String filename) {
if (filename.endsWith(".java")) return true;
return false;
}
}
import
java.io.*;
public
class JavaFilterTest {
public static void main (String args[])
{
JavaFilter jf = new
JavaFilter();
File dir = new
File("args[0]");
String file =
args[1];
if
(jf.accept(dir, file))
System.out.println("OK - Java source datoteka");
else
System.out.println("Nije Java source datoteka");
}
}
% javac JavaFilter.java
% javac JavaFilterTest.java
% java JavaFilterTest
"." "JavaFilter.java"
OK – Java source datoteka
% java JavaFilterTest "." "JavaFilter.class"
Nije Java source datoteka
%
Ime ne mora biti jedini kriterij filtriranja. Možete testirati datum zadnje promjene, dozvole, veličinu i drugo. Na primjer, sljedeća accept() metoda testira da li datoteka završava ekstenzijom .java i da li je u direktoriju za koji imate dozvolu pisanja.
public boolean accept(File directory, String filename) {
if (
filename.endsWith(".java") && directory.canWrite()) return true;
return false;
}
Klase
java.io.Reader
i java.io.Writer
su apstraktne nadklase klasama koje obavljaju čitanje i pisanje podataka
zasnovanih na znakovima (characters). Značajne su za konvertiranje
znakova između različitih znakovnih sustava (character sets).
Ulazni i izlazni streamovi su općenito zasnovani na byteovima, no klase Reader i Writer su zasnovani na znakovima koji mogu imati različite veličine, ovisno o sustavu znakova. Na primjer ASCII i ISO Latin-1 koriste znakove veličine jedan byte. Unicode koristi znakove od dva bytea. UTF-8 koristi znakove varijabilne duljine, od jednog do tri bytea. Reader i Writer znaju kako rukovati tim znakovnim sustavima kao i mnogim drugim.
Metode
iz klase java.io.Reader
namjerno su napravljene tako da budu slične metodama iz klase java.io.InputStream
.
Međutim, umjesto da rade s byteovima, one rade sa znakovima (char).
Osnovna
read()
metoda čita pojedinačni znak (koji može zauzimati od jednog do četiri bytea,
ovisno o znakovnom sustavu) i vraća ga kao int između 0 i 65535. Ako naiđe na
kraj strama, vraća -1.
public int read() throws IOException
Možete učitati i više znakova odjednom u polje znakova. Metode koje to rade vraćaju broj uspješno učitanih znakova ili -1 ako naiđu na kraj streama.
public int read(char[] text) throws IOException
public abstract int read(char[] text, int offset, int length) throws IOException
Sve
read()
metode
blokiraju se ako nije dostupan neki input, ako se pojavi I/O error ili ako naiđu
na kraj streama.
Možete preskočiti određeni broj znakova pomoću metode skip(). Ona će se također blokirati ako nema dostupnog inputa. Vraća broj preskočenih znakova ili -1 ako je naišla na kraj streama.
public long skip(long n) throws IOException
Metoda
ready()
vraća true
ako je Reader
spreman za čitanje, false
inače. Općenito će to biti ako pripadni stream ima dostupnih podataka.
public boolean ready() throws IOException
Reader
može ili ne mora podržavati markiranje i resetiranje. Metoda markSupported()
vraća true
ako
pripadni stream podržava markiranje i resetiranje, false
inače.
public boolean markSupported()
public void mark(int readAheadLimit) throws IOException
public void reset() throws IOException
Konačno,
metoda close()
zatvara stream i otpušta resurse koji su s njim povezani.
public abstract void close() throws IOException
Metode
iz klase java.io.Writer
namjerno su napravljene tako da budu slične metodama iz java.io.OutputStream
.
Međutim, umjesto da rade s byteovima, one rade sa znakovima (char).
Osnovna
write()
metoda ispisuje pojedinačni znak od dva bytea s vrijednošću između 0 i 65535.
Vrijednost se uzima iz dva niža bytea argumenta c
(preostala dva viša bytea se ignoriraju). Podklase koje žele efikasno pisati
znakove morat će prekriti ovu metodu.
public void write(int c) throws IOException
Možete također ispisati polje znakova, podpolje znakova, string ili substring.
public void write(char[] text) throws IOException
public abstract void write(char[] text, int offset, int length) throws IOException
public void write(String s) throws IOException
public void write(String s, int offset, int length) throws IOException
Kao
svi izlazni streamovi, i ovi će možda biti bufferirani na razini operacijskog
sustava. Ako želite sami odrediti kad će se ispis izvršiti, pozovite metodu
flush()
.
public abstract void flush() throws IOException
Konačno,
metoda close()
zatvara stream i otpušta resurse koji su s njim povezani.
public abstract void close() throws IOException
Klasa
java.io.InputStreamReader
služi kao most između streamova byteova i streamova znakova. Čita byteove s
ulaznog streama i prevodi ih u znakove u skladu sa zadanim znakovnim sustavom.
Znakovni sustav (encoding) može se zadati u konstruktoru ili se može prihvatiti default sustav s računala.
public InputStreamReader(InputStream in)
public InputStreamReader(InputStream in, String encoding) throws UnsupportedEncodingException
Na
primjer, da biste priključili InputStreamReader
na System.in
sa pretpostavljenim znakovnim sustavom (najčešće ISO Latin-1), stavili biste:
InputStreamReader isr = new InputStreamReader(System.in);
S druge strane, ako želite čitati datoteku koja je bila napisana u fontu Macintosh Symbol, možete to učiniti ovako:
FileInputStream fis = new FileInputStream("symbol.txt");
InputStreamReader isr = new InputStreamReader(fis, "MacSymbol");
Metoda
getEncoding()
vraća string koji sadrži ime znakovnog sustava koji se trenutno koristi.
public String getEncoding()
Ostale
metode prekrivaju metode iz java.io.Reader
,
ali se, iz programerove perspektive, ponašaju na isti način kao i one.
public int read() throws IOException
public int read(char c[], int off, int length) throws IOException
public boolean ready() throws IOException
public void close() throws IOException
Klasa
java.io.OutputStreamWriter
povezuje izlazne byte streamove i znakovne streamove. Ispisuje byteove na
pripadni izlazni stream nakon prevođenja znakova u skladu sa zadanim znakovnim
sustavom.
Znakovni sustav može se zadati u konstruktoru ili se može prihvatiti default sustav sa platforme.
public OutputStreamWriter(OutputStream out, String enc) throws UnsupportedEncodingException
public OutputStreamWriter(OutputStream out)
Na
primjer, da biste priključili OutputStreamWriter
na System.out
sa pretpostavljenim znakovnim sustavom (najčešće ISO Latin-1), stavili
biste:
OutputStreamWriter osw = new OutputStreamWriter(System.out);
S druge strane, ako želite pisati u datoteku u Macintosh Symbol fontu, možete to učiniti ovako:
FileOutputStream fos = new FileOutputStream("symbol.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos, "MacSymbol");
Metoda
getEncoding()
vraća
string koji sadrži ime znakovnog sustava koji se trenutno koristi.
public String getEncoding()
Ostale
metode prekrivaju metode iz java.io.Writer
,
ali se, iz programerove perspektive, ponašaju na isti način kao i one.
public void write(int c) throws IOException
public void write(char c[], int offset, int length) throws IOException
public void write(String s, int offset, int length) throws IOException
public void flush() throws IOException
public void close() throws IOException
Ime |
Znakovni
sustav |
8859_3 |
ISO 8859-3 (Latin Extended-B) Pinyin, Sami, Croatian, and a few others |
8859_4 |
ISO 8859-4 (Latin Extended-C) |
8859_5 |
ISO 8859-5 Latin/Cyrillic |
8859_6 |
ISO 8859-6 Latin/Arabic |
8859_7 |
ISO 8859-7 Latin/Greek |
8859_8 |
ISO 8859-8 Latin/Hebrew |
8859_9 |
ISO 8859-9 Latin/Turkish |
Big5 |
The Big 5 encoding for Chinese |
CNS11643 |
Chinese |
Cp037 |
EBCDIC American English |
Cp273 |
IBM273 |
Cp277 |
EBCDIC Danish/Norwegian |
Cp278 |
EBCDIC Finnish/Swedish |
Cp280 |
EBCDIC Italian |
Cp284 |
EBCDIC Spanish |
Cp285 |
EBCDIC UK English |
Cp297 |
EBCDIC French |
Cp420 |
EBCDIC Arabic 1 |
Cp424 |
EBCDIC Hebrew |
Cp437 |
the original DOS IBM PC character set, essentially ASCII with a few extra characters for drawing lines and boxes |
Cp500 |
EBCDIC Flemish/Romulsch |
Cp737 |
DOS Greek |
Cp775 |
DOS Baltic |
Cp850 |
DOS Latin-1 |
Cp852 |
DOS Latin-2 |
Cp855 |
DOS Cyrillic |
Cp856 |
IBM856 |
Cp857 |
DOS Turkish |
Cp860 |
DOS Portuguese |
Cp861 |
DOS Icelandic |
Cp862 |
DOS Hebrew |
Cp863 |
DOS Canadian French |
Cp864 |
DOS Arabic |
Cp865 |
IBM865 |
Cp866 |
IBM866 |
Cp868 |
EBCDIC Arabic |
Cp869 |
DOS modern Greek |
Cp870 |
EBCDIC Serbian |
Cp871 |
EBCDIC Icelandic |
Cp874 |
Windows Thai |
Cp875 |
IBM875 |
Cp918 |
EBCDIC Arabic 2 |
Cp921 |
IBM921 |
Cp922 |
IBM922 |
Cp1006 |
IBM1006 |
Cp1025 |
IBM1025 |
Cp1026 |
IBM1026 |
Cp1046 |
IBM1046 |
Cp1097 |
IBM1097 |
Cp1098 |
IBM1098 |
Cp1112 |
IBM1112 |
Cp1122 |
IBM1122 |
Cp1123 |
IBM1123 |
Cp1124 |
IBM1124 |
Cp1250 |
Windows Eastern European (essentially ISO Latin-2) |
Cp1251 |
Windows Cyrillic |
Cp1252 |
Windows Western European (essentially ISO-Latin-1) |
Cp1253 |
Windows Greek |
Cp1254 |
Windows Turkish |
Cp1255 |
Windows Hebrew |
Cp1256 |
Windows Arabic |
Cp1257 |
Windows Baltic |
Cp1258 |
Windows Vietnamese |
EUCJIS |
Japanese EUC |
GB2312 |
Chinese |
JIS |
Japanese Hiragana |
JIS0208 |
Japanese |
KSC5601 |
Korean |
MacArabic |
The Macintosh Arabic character set |
MacCentralEurope |
The Macintosh Central European character set |
MacCroatian |
The Macintosh Croatian character set |
MacCyrillic |
The Macintosh Cyrillic character set |
MacDingbat |
Zapf Dingbats |
MacGreek |
The Macintosh modern Greek character set |
MacHebrew |
The Macintosh Hebrew character set |
MacIceland |
The Macintosh Icelandic character set |
MacRoman |
The Macintosh Roman character set |
MacRomania |
The Macintosh Romanian character set |
MacSymbol |
The Symbol font (includes a complete Greek alphabet in place of the usual Roman letters) |
MacThai |
The Macintosh Thai character set |
MacTurkish |
The Macintosh Turkish character set |
MacUkraine |
The Macintosh Ukrainian character set |
SJIS |
Windows Japanese |
UTF8 |
UCS Transformation Format, 8-bit form |
Unicode |
Normal Unicode |
UnicodeBig |
Unicode with big-endian byte order |
Primijetite da to što Java zna raditi s određenim znakovnim sustavom još ne znači da na računalu automatski postoje fontovi koji su potrebni da bi se znakovi iz tog sustava prikazali.
Klasa
java.io.FileWriter
služi za pisanje tekstualnih datoteka koristeći pretpostavljeni znakovni sustav
i veličinu spremnika s platforme. Ako želite promijeniti te vrijednosti,
konstruirajte OutputStreamWriter
i priključite ga na FileOutputStream
.
Ova klasa nema vlastitih metoda (samo naslijeđene), a deklarirani su samo
konstruktori.
public FileWriter(String fileName) throws IOException
public FileWriter(String fileName, boolean append) throws IOException
public FileWriter(File file) throws IOException
public FileWriter(FileDescriptor fd)
Pogledajmo primjer:
FileWriter fw = new FileWriter("izlaz.txt");
The
java.io.FileReader
služi za čitanje tekstualnih koristeći pretpostavljeni znakovni sustav i
veličinu spremnika s platforme. Ako želite promijeniti te vrijednosti,
konstruirajte InputStreamReader
i priključite ga na FileInputStream
.
Ova klasa nema vlastitih metoda (samo naslijeđene), a deklarirani su samo
konstruktori.
public FileReader(String fileName) throws FileNotFoundException
public FileReader(File file) throws FileNotFoundException
public FileReader(FileDescriptor fd)
Pogledajmo primjer:
FileReader fr = new FileReader("36.html");
Klasa
java.io.BufferedReader
je podklasa od java.io.Reader
koju možete ulančiti s drugom Reader
klasom
zbog bufferiranja znakova. To omoućuje efikasnije čitanje znakova i linija.
Klasa
BufferedReader
također je značajna i zbog svoje readLine()
metode koja omogućuje čitanje teksta liniju po liniju.
Kod
svakog čitanja s nebufferiranog Reader
a,
obavlja se i odgovarajuće čitanje s pridruženog ulaznog streama. Zato nije loša
ideja priključiti BufferedReader
na svaki Reader
čije
su operacije čitanja skupe, kao npr. za FileReader
.
Na primjer,
BufferedReader br = new
BufferedReader(new FileReader("ulaz.txt"));
Dva su konstruktora, jedan sa pretpostavljenom veličinom spremnika od 8192 znaka, dok drugi dozvoljava specificiranje veličine spremnika:
public BufferedReader(Reader in, int sz)
public BufferedReader(Reader in)
Jedina
nova metoda u toj klasi je readLine()
:
public String readLine() throws IOException
Ona
vraća String
koji
sadrži liniju teksta iz tekstualne datoteke. Nizovi \r,
\n,
i \r\n
su pretpostaljeni znakovi za prijelaz u novi redak i nisu uključeni u vraćeni
String
. U
sljedećem primjeru čita se tekstualna datoteka, redak po redak i ispisuje se na
System.out:
// Implement the Unix cat utility in Java
import java.io.*;
class cat {
public static void main (String args[]) {
String thisLine;
//Loop across the arguments
for (int i=0; i < args.length; i++) {
//Open the file for reading
try {
BufferedReader br = new BufferedReader(new FileReader(args[i]));
while ((thisLine =
br.readLine()) != null) { // while loop begins here
System.out.println(thisLine);
} // end while
} // end try
catch (IOException e) {
System.err.println("Error: " + e);
}
} // end for
} // end main
}
% javac cat.java
% java cat "../html/TricksterApplet.html" "../html/GridBagCalculator.html"
<APPLET CODE="TricksterApplet.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="Trickster.jar"
WIDTH=1 HEIGHT=1>
</APPLET>
<APPLET CODE="GridBagCalculatorApplet.class"
CODEBASE="http://student.math.hr/~vedris/java/classes"
ARCHIVE="GridBagCalculator.jar"
WIDTH=1 HEIGHT=1>
</APPLET>
%
Klasa
BufferedReader
dopušta markiranje i resetiranje, barem do duljine spremnika.
public boolean markSupported()
public void mark(int readAheadLimit) throws IOException
public void reset() throws IOException
Konačno,
BufferedReader
prekriva nekoliko metoda iz svoje nadklase Reader
,
ali se način njihove uporabe uopće ne mijenja.
public int read() throws IOException
public int read(char c[], int off, int length) throws IOException
public long skip(long n) throws IOException
public boolean ready() throws IOException
public void close() throws IOException
Klasa
java.io.LineNumberReader
je podklasa od java.io.BufferedReader
koja vodi računa o tome s koje linije trenutačno čitate. Ima sve metode kao i
BufferedReader
uključjujći i readLine()
.
Ima dva konstruktora i dvije nove metode, getLineNumber()
i setLineNumber()
:
public LineNumberReader(Reader in)
public LineNumberReader(Reader in, int size)
public void setLineNumber(int lineNumber)
public int getLineNumber()
Metoda
setLineNumber()
ne mijenja file pointer. Ona samo mijenja vrijednost koju vraća getLineNumber()
.
To vam, na primjer, omogućuje da počnete brojiti od -5 ako znate da ima šest
linija headera za koje ne želite da uđu u numeraciju.
U
sljedećem primjeru čita se tekstualna datoteka, redak po redak i ispisuje se na
System.out
no
ispred svake linije ispisuje se njen broj:
import java.io.*;
class linecat {
public static void main (String args[]) {
String thisLine;
//Loop across the arguments
for (int i=0; i < args.length; i++) {
//Open the file for reading
try {
LineNumberReader br = new LineNumberReader(new FileReader(args[i]));
while ((thisLine = br.readLine()) != null) { // while loop begins here
System.out.println(
br.getLineNumber() + ": " + thisLine);
} // end while
} // end try
catch (IOException e) {
System.err.println("Error: " + e);
}
} // end for
} // end main
}
% javac linecat.java
% java linecat "../html/TricksterApplet.html" "../html/GridBagCalculator.html"
1: <APPLET CODE="TricksterApplet.class"
2: CODEBASE="http://student.math.hr/~vedris/java/classes"
3: ARCHIVE="Trickster.jar"
4: WIDTH=1 HEIGHT=1>
5: </APPLET>
1: <APPLET CODE="GridBagCalculatorApplet.class"
2: CODEBASE="http://student.math.hr/~vedris/java/classes"
3: ARCHIVE="GridBagCalculator.jar"
4: WIDTH=1 HEIGHT=1>
5: </APPLET>
%
Klasa
java.io.BufferedWriter
je podklasa od java.io.Writer
koju možete ulančiti s drugom Writer
klasom
zbog bufferiranja znakova. To omogućuje efikasnije ispisivanje teksta.
Svaki
put kad pišete na nebufferirani Writer
,
obavlja se i pisanje na pridruženi izlazni stream. Zato nije loša ideja
priključiti BufferedWriter
na svaki Writer
čije operacije pisanja su skupe, a ne traže trenutačni odziv. Pogledajmo taj
postupak npr. za FileWriter
:
BufferedWriter bw = new BufferedWriter(new FileWriter("izlaz.txt"));
There are two constructors, one with a default buffer size of 8192 characters, and one that lets you specify the buffer size:
public BufferedWriter(Writer out)
public BufferedWriter(Writer out, int size)
U
ovoj klasi nova je metoda newLine()
koja
ispisuje string za završetak linije. On je ovisan o platformi pa tako imamo
\n
za Unix, \r
za Mac, \r\n
za Windows.
public String newLine() throws IOException
Konačno,
BufferedWriter
prekriva nekoliko metoda iz svoje nadklase Writer
;
ali način njihove uporabe ostaje isti:
public void write(int c) throws IOException
public void write(char c[], int off, int length) throws IOException
public void write(String s, int offset, int length) throws IOException
public void flush() throws IOException
public void close() throws IOException
Klasa
java.io.PrintWriter
je podklasa od java.io.Writer
koja omogućuje korištenje poznatih metoda print()
i
println()
.
Vrlo je slična klasi java.io.PrintStream.
Glavna razlika je u pravilnom rukovanju višestrukim byteovima i znakovnim
sustavima koji nisu ISO Latin-1. Druga razlika je u tome što se automatski ispis
(flushing) obavlja tek kad se pozove neka od println()
metoda, a ne svaki put kad se pojavi znak za novi redak.
Tendencija
proizvođača je izbaciti iz uporabe PrintStream
i umjesto njega koristiti PrintWriter
,
no to bi dovelo do pucanja velike količine već postojećeg koda.
public PrintWriter(Writer out)
public PrintWriter(Writer out, boolean autoFlush)
public PrintWriter(OutputStream out)
public PrintWriter(OutputStream out, boolean autoFlush)
public void flush()
public void close()
public boolean checkError()
protected void setError()
public void write(int c)
public void write(char buf[], int offset, int length)
public void write(char buf[])
public void write(String s,
public void write(String s)
public void print(boolean b)
public void print(char c)
public void print(int i)
public void print(long l)
public void print(float f)
public void print(double d)
public void print(char s[])
public void print(String s)
public void print(Object obj)
public void println()
public void println(boolean x)
public void println(char x)
public void println(int x)
public void println(long x)
public void println(float x)
public void println(double x)
public void println(char x[])
public void println(String x)
public void println(Object x)