Predavanje br. index|1|2|3|4|5|6|7|8|9|10|11|12|13|14|HOME


Deseto predavanje – ulaz i izlaz

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


Operacije ulaza i izlaza

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.


Što je Stream?

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>.


Klase streamova

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:


Odakle streamovi dolaze?

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 InputStream

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.


Čitanje byteova

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>
%

Čitanje više byteova odjednom

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.


Prebrojavanje dostupnih byteova

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>
%

Preskakanje byteova

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();
         }

Markiranje i resetiranje

Č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.


Zatvaranje streamova

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.


Izlazni streamovi

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.


Primjer izlaznog streama

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.


Čitanje iz datoteke

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.


Primjer čitanja 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>
%

Pisanje u datoteku

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.


Primjer pisanja 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
%

Dodavanje na kraj datoteke

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.
%

Filtriranje streamova

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"));

Filtrirani streamovi

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)

 

PrintStream

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.

 

PushbackInputStream

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.


Bufferirani streamovi

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 podatkovnih streamova

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 PrintStream

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

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 File

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.

Napomena za C programere

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()).


Konstruktori klase File

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.


Metode klase File

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().


Primjeri metoda iz klase File

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 FileDialog

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:

  1. Kreirati novi FileDialog
  2. Učiniti FileDialog vidljivim.
  3. Odabrati ime direktorija i ime datoteke.

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.


Klasa RandomAccessFile

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 FilenameFilter

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 Reader i Writer

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.


Klasa Reader

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

Klasa Writer

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 InputStreamReader

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 OutputStreamWriter

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

Dostupne kodne stranice

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 FileWriter

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");

Klasa FileReader

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 BufferedReader

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 Readera, 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 LineNumberReader

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 BufferedWriter

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 PrintWriter

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)