Dione
Z. KotalaP. Toman: Java
Predchozi (Obsah) Dalsi

15. Práce s datovými proudy

Balík java.io obsahuje třídy, které slouží pro zpracování datových výstupů a vstupů. Pro obvyklou práci se soubory zde můžeme najít třídy File a RandomAccessFile.

Většina tříd se však věnuje práci s datovými proudy. A to jak binárními jejichž hlavní zastánci jsou třídy OutputStream a InputStream, tak i znakovými jejichž hlavní třídy jsou Writer a Reader. Od hlavních tříd je pak odvozena řada potomků, kteří se specializují na určité datové proudy.

V následujících podkapitolách můžete najít stručný popis hlavních tříd s některými jejich metodami.

15.1. Třída File

Třída File umožňuje nezávisle na platformě definovat názvy souborů a adresářů. Dále nabízí metody pro ověření existence, možnosti přístupu (čtení/zápis), výpis souboru v adresáři, vytváření adresářů, přejmenování adresářů/souborů a jejich mazání.

  • public boolean exist() - test zda soubor/adresář existuje,

  • public boolean isDirectory() - test na adresář,

  • public boolean isFile() - test na soubor,

  • public boolean canRead() - test na čtení souboru,

  • public boolean canWrite() - test na zápis do souboru,

  • public String getName() - vrací jméno souboru zbavené jmen adresářů,

  • public String getPath() - vrací jméno souboru s kompletní cestou,

  • public String getParent() - vrací kompletní cestu k souboru,

  • public long length() - vrací délku souboru,

  • public boolean mkdir() - vytvoří adresář,

  • public boolean mkdirs() - vytvoří adresář i s podadresáři,

  • public boolean delete() - smaže soubor/adresář,

  • public boolean renameTo(File cíl) - přejmenuje soubor,

  • public String[] list() - zjistí všechny soubory/adresáře odpovídající zadanému jménu při vytvoření objektu.

 

Priklad 15.1.
File soubor = new File("soubor.txt");
System.out.println("Délka souboru: " + soubor.length);

15.2. Třída RandomAccessFile

Tato třída umožňuje náhodný přístup k souboru a práci s ním. Otevření souboru se provede při vytváření objektu konstruktorem. Ve třídě RandomAccessFile jsou definovány dva veřejné konstruktory a to:

   public RandomAccessFile(String soubor, String mód);
   public RandomAccessFile(File soubor, String mód);

Parametr mód může být buď "r" pro otevření souboru jen pro čtení, nebo "rw" pro otevření souboru pro zápis i čtení. Po otevření souboru je vždy nastaveno ukazovátko na začátek souboru, a to v obou módech. Ani jeden mód neruší obsah souboru.

  • public native long getFilePointer() - vrací aktuální pozici v souboru,

  • public native long length() - zjistí délku souboru,

  • public native void seek(long poz) - nastaví pozici v souboru na poz,

  • public native void close() - zavře soubor,

  • public native int read() - načte jeden byte,

  • public int read(byte b[]) - načte b.length bytů,

  • public final boolean readBoolean(), byte readByte(),
    char readChar(), ... - načte primitivní datový typ,

  • public final String readLine() - načte řetězec v Unicode (viz příloha C.),

  • public final String readUTF() - načte řetězec v UTF kódování (viz C.1.),

  • public native void write(int b) - zapíše byte(!),

  • public void write(byte b[]) - zapíše b.length bytů,

  • public final void writeBoolean(boolean v), void
    writeByte(byte v)
    , void writeChar(char v), ... - zapíše primitivní datový typ,

  • public final void writeBytes(String s) - zapíše řetězec jako sled bytů,

  • public final void writeChars(String s) - zapíše řetězec jako sled znaků,

  • public final void writeUTF(String s) - zapíše řetězec v kódování UTF,

Priklad 15.2.
import java.io.*;
public class KopirovaniSouboru
{
  public static void main(String[] argv) throws IOException  {
     if (argv.length != 2) return;
     File soubor1 = new File(argv[0]);
     File soubor2 = new File(argv[1]);
     if (!soubor1.isFile()) return;
     if (soubor2.exists()) soubor2.delete();
     RandomAccessFile zdroj = new RandomAccessFile(soubor1,"r");
     RandomAccessFile cil   = new RandomAccessFile(soubor2,"rw");
     for (int n = 0; n < soubor1.length(); n++)
        cil.writeByte(zdroj.readByte());
     zdroj.close();
     cil.close();
  }
}

15.3. Třída InputStream

Abstraktní třída InputStream je rodičovskou třídou všech vstupních bytových datových proudů. Definuje základní metody pro jejich zpracování.

  • public InputStream() - veřejný konstruktor,

  • public abstract int read() - načte byte,

  • public int read(byte b[]) - načte b.length bytů,

  • public void close() - zavře vstupní datový proud,

  • public long skip(long n) - přeskočí n bytů na vstupu,

  • public boolean markSupported() - vrací true pokud vstupní datový proud podporuje "značkování",

  • public synchronized void mark(int limit) - nastaví značku v datovém proudu,

  • public synchronized void reset() - vrací se zpět na značku.

Metodou mark() si lze označit aktuální pozici ve vstupním proudu a metodou reset() se lze pak na tuto pozici vrátit. Pokud přesáhne počet načtených bytů hodnotu, kterou udává parametr limit metody mark, je značka zrušena. Tyto dvě metody lze však použít pouze tehdy, vrátí-li metoda markSupported() hodnotu true.

Od abstraktní třídy InputStream jsou pak odvozeny například třídy:

  • FileInputStream - umožňuje přístup k souborům na nízké úrovni, proto je používaná pro vlastní čtení metodami jiných tříd. Například třídou DataInputStream.

  • FilterInputStream - poskytuje metody, které lze použít pro filtrování dat ze vstupního proudu. Vlastní filtrování však provádí její potomci. Mezi ně patří např. již zmiňovaná třída DataInputStream.

  • PipedInputStream - slouží k vytvoření roury pro komunikaci mezi vlákny (viz kap. 16.).

15.4. Třída OutputStream

OutputStream je abstraktní třída definující metody pro bytový výstupní proud. Je rodičovskou třídou všech výstupních proudů.

  • public OutputStream() - veřejný konstruktor,

  • public abstract void write(int b) - zapíše byte(!),

  • public void write(byte b[]) - zapíše b.length bytů,

  • public void flush() - vyprázdní výstupní vyrovnávací paměť,

  • public void close() - zavře datový proud.

Mezi potomky třídy OutputStream patří např. FilterOutputStream, FileOutputStream či PipedOutputStream. Tyto třídy jsou obdobou tříd odvozených od třídy InputStream.

15.5. Třída Reader

Reader je abstraktní třída definující metody všech znakově orientovaných vstupních datových proudů.

  • public boolean ready() - zjistí, zda je k dispozici další znak,

  • public int read() - načte jeden znak,

  • public int read(char c[]) - načte c.length znaků,

  • public abstract void close() - zavře vstupní datový proud,

  • public long skip(long n) - přeskočí (ignoruje) n znaků na vstupu,

  • public boolean markSupported() - vrací true pokud vstupní datový proud podporuje "značkování",

  • public void mark(int limit) - nastaví značku v datovém proudu,

  • public void reset() - vrací se zpět na značku.

Funkce metod je obdobná jako u třídy InputStream.

15.6. Třída Writer

Writer je abstraktní třída definující metody všech znakově orientovaných výstupních datových proudů.

  • public void write(int c) - zapíše jeden znak,

  • public void write(char c[]) - zapíše c.length znaků,

  • public void write(String s) - zapíše řetězec,

  • void flush() - vyprázdní výstupní vyrovnávací paměť,

  • public abstract void close() - zavře datový proud.

Funkce metod je obdobná jako u třídy OutputStream.

Priklad 15.3.
import java.io.*;
public class KopirovaniProudu
{
  public static void main(String[] argv) throws IOException  {
     if(argv.length != 2) return;
     File soubor1 = new File(argv[0]);
     File soubor2 = new File(argv[1]);
     if(!soubor1.isFile()) return;
     if(soubor2.exists()) soubor2.delete();
     FileInputStream zdroj = new FileInputStream(soubor1);
     FileOutputStream cil   = new FileOutputStream(soubor2);
     for(int n = 0; n < soubor1.length(); n++)
       cil.write(zdroj.read());
     zdroj.close();
     cil.close();
  }
}

15.7. Standardní vstup a výstup

Standardní vstup a výstup je definován v třídě java.lang.System. V této třídě je definován i standardní chybový výstup.

Standardní vstup je označen identifikátorem in a je to instance třídy InputStream. Oba výstupy jsou instancemi třídy PrintStream, která je odvozena od třídy FilterOutputStream. Standardní výstup je označen identifikátorem out, chybový výstup pak identifikátorem err.

Třída PrintStream nabízí statické metody:

   print( parametr )
   println( parametr )

kde parametr může být některý z primitivních datových typů boolean, char, double, float, int, long a samozřejmě String.

Priklad 15.4.
System.out.print("Rozbijte wokna!");
System.out.println(1011);

Čtení z klávesnice je poněkud komplikovanější, jelikož abstraktní třída InputStream nabízí jen metodu read() pro načtení jednoho bytu ze vstupu.

Priklad 15.5.
Načtení řetězce o max. délce 30 znaků z klávesnice může vypadat takto:

byte pole[] = new byte[30];                 // (1) 

System.in.read(pole);                       // (2) 
String text = new String(pole);             // (3) 
System.out.println("Zadal jsi: " + text);   // (4) 

Na řádce (1) je deklarováno bytové pole, do kterého je následně načten vstup metodou read (2). Maximální délka vstupu je omezena hodnotou pole.length. Vstup se ukončí klávesou ENTER. Pokud je vstup delší je automaticky oříznut. Jelikož však vstup z klávesnice umožňuje vstup znaků v ASCII kódu je nutné provést převod na Unicode. Na řádce (3) je k tomuto účelu použít konstruktor třídy String, který převede bytové pole na řetězec. Z tohoto je zřejmé, že tento převod lze použít pro znaky 0-127 ASCII tabulky (viz příloha C.). Poslední řádka (4) pak načtený výsledek zobrazí.

Pozn.: Základní datové typy je vhodné nejdříve načíst jako řetězec a pak provést konverzi.

Pozn.: Jelikož Java je orientována na grafická rozhraní, je výhodnější používat pro vstup a výstup knihovnu AWT (viz příloha A.).


Predchozi
Converted by Selathco v0.9 on 25.09.1999 19:46
Dalsi