autor: Ivan Kupka

Verzia 1

home uvod K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 K13 K14

 

Java 8

 

Súbory. Vstup a výstup

 

  Ciele kapitoly: oboznámiť sa s triedou File a jej základnými metódami. Práca s adresármi a súbormi.  Čítanie zo súboru a zapisovanie do súboru. Vstup z klávesnice. Základné typy prúdov. Bufferovanie.

 

 

 

Trieda File umožňuje základnú prácu s adresármi a súbormi. Je triedou balíka java.io.  Pozrime si prácu niektorých jej metód na príklade. V nasledujúcom kóde uvidíme príklad týchto činností:

 

1.     Zistíme si meno aktuálneho adresára.

 

2.     Vytvoríme nový podadresár.

 

3.     Dáme si vymenovať jeho podsúbory a podadresáre

 

4.     V podadresári vytvoríme nový súbor. (Nebudeme doňho písať, to trieda File nedokáže.)

 

5.     Zistíme, či v podadresári existuje súbor „help.txt“.

 

6.     Premenujeme súbor v podadresári.

 

7.     Vytvoríme nové adresáre po ceste „ C:\Anicka\mam\ta\rad” .

 

Kód P8.1

 

import java.io.*;

 

 

 

public class Subory{

 

          public static void main(String[] args){

 

          //1.     Zistime si meno aktualneho adresara.

 

          String menoAktAdresara = System.getProperty("user.dir");

 

          System.out.println("Meno aktualneho adresara je: " + menoAktAdresara);

 

//2.     Vytvorime novy podadresar.

 

// najprv musime vytvorit instanciu triedy File

 

    File podadresar = new File("novyPodadresar");

 

    // existuje v aktualnom adresari adresar alebo subor s tymto menom?

 

    System.out.println(" novyPodadresar existuje = " + podadresar.exists());

 

    // teraz ho vytvorime

 

    podadresar.mkdir();

 

    // zistime, ci existuje

 

    System.out.println(" novyPodadresar existuje = " + podadresar.exists());

 

//3.     Dame vymenovat subory a podadresare v aktualnom adresari ako Stringy.

 

// najprv musime vytvorit instanciu triedy File pre aktualny adresar

 

  File aktAdresar = new File(menoAktAdresara);

 

  String[] names = aktAdresar.list();

 

  System.out.println("Aktualny adresar obsahuje: ");

 

  for(int i = 0; i < names.length; i++){

 

    System.out.println(names[i]);

 

  }

 

  // mozme ziskat aj zoznam suborov a adresarov ako pole typu File

 

  File[] subory = aktAdresar.listFiles();

 

  for(int i = 0; i < subory.length; i++){

 

    System.out.println(subory[i].getName() + "  absolutna cesta: " + subory[i].getAbsolutePath());

 

  }

 

 

 

//4.     V podadresari vytvorime nový súbor.

 

File suborcek = new File(podadresar,"suborcek.txt");

 

//System.out.println("V podadresari je subor: " + (podadresar.list())[0]);  - chyba

 

// najprv treba subor vytvorit

 

try{

 

suborcek.createNewFile();

 

}

 

catch(IOException e){

 

System.out.println("Chyba pri tvoreni suboru.");   

 

}

 

System.out.println("V podadresari je subor: " + (podadresar.list())[0]);

 

//5.     Zistíme, ci v podadresári existuje súbor "help.txt".

 

File tenHelp = new File(podadresar,"help.txt");

 

System.out.println(" V podadresari " + podadresar + " Existuje subor  help.txt " + tenHelp.exists());

 

//6.     Premenujeme súbor v podadresári.

 

// takto to nejde: suborcek.renameTo("premenovany.subor");

 

  File nahradny = new File(podadresar,"premenovany.subor");

 

  suborcek.renameTo(nahradny);

 

//7. vytvorime nove adresare

 

// najprv si nachystame cestu

 

String s = File.separator;

 

String cesta = "C:" + s + "Anicka" + s + "mam" + s + "ta" + s + "rad";

 

File celaCesta = new File(cesta);

 

System.out.println("Adresar "  + cesta + " existuje = " + celaCesta.exists());

 

celaCesta.mkdirs();

 

System.out.println("Adresar "  + cesta + " existuje = " + celaCesta.exists());

 

 

 

          }

 

}

 

         

 

Jeden možný výstup:

 

Meno aktualneho adresara je: D:\Ivan\Java\vyuc 8

 

 

 novyPodadresar existuje = false

 

 

 novyPodadresar existuje = true

 

 

Aktualny adresar obsahuje:

 

 

novyPodadresar

 

 

Subory.class

 

 

Subory.java

 

 

vyuc 8.kawa

 

 

novyPodadresar  absolutna cesta: D:\Ivan\Java\vyuc 8\novyPodadresar

 

 

Subory.class  absolutna cesta: D:\Ivan\Java\vyuc 8\Subory.class

 

 

Subory.java  absolutna cesta: D:\Ivan\Java\vyuc 8\Subory.java

 

 

vyuc 8.kawa  absolutna cesta: D:\Ivan\Java\vyuc 8\vyuc 8.kawa

 

 

V podadresari je subor: premenovany.subor

 

 

 V podadresari novyPodadresar Existuje subor  help.txt false

 

 

Adresar C:\Anicka\mam\ta\rad existuje = false

 

 

Adresar C:\Anicka\mam\ta\rad existuje = true

 

 

Process Exit...

 

 

 

 V kóde sme použili  statickú premennú triedy File typu String: File.separator (vo Windowsoch je

 

to „\“).  Všimnite si rozdiel pri práci metód „mkdir()“ a „mkdirs()“. Prvá vytvorí len jeden adresár, druhá všetky adresáre, vymenované na danej ceste. Všetky potrebné detaily ku metódam, používaným v kóde sa dajú nájsť v dokumentácii triedy File. Metódy list()  a listFiles() majú aj svoje preťažené varianty s argumentom typu FilenameFilter. FilenameFilter je rozhranie, ktoré po implementovaní umožní metódam list() a listFiles() vypísať len tie súbory, ktoré spĺňajú určité kritériá. Tie, ktoré sme nastavili pomocou inštancie typu FilenameFilter a jej metódy „accept“. Ďalšie detaily – znova v dokumentácii rozhrania FilenameFilter.

 

 

 

Prenos informácie pomocou prúdov. Štyri základné abstraktné triedy

 

 Termín „prúd dát“ sa v Jave používa na označenie vstupu-výstupu. Každý prúd dát je systémom pripojený na nejaké fyzické zariadenie vstupu alebo výstupu, poprípade na pamäť patriacu nejakému objektu (napr. vláknu) , programu,  či na údaje obsiahnuté v súbore, alebo uskladnené niekde na sieti.  Java implementuje prúdy dát v balíku java.io.

 

  V jave existujú dva základné typy prúdov:

 

Znakovo orientované prúdy – základná jednotka dát je 16-bitová pre znaky Unicode. Základné abstraktné triedy, slúžiace na vytváranie takýchto prúdov sú triedy Reader a Writer.

 

Bajtovo orientované prúdy – odvodené od abstraktných tried InputStream a OutputStream.

 

  Napríklad „System.out “ je statický člen triedy „System“, ktorý je typu PrintStream . PrintStream je trieda , dediaca od triedy java.io.FilterOutputStream a táto je už priamym potomkom abstraktnej triedy java.io.OutputStream.

 

 

 

Od štyroch abstraktných tried Reader, Writer, InputStream  a OutputStream je odvodených množstvo špecializovaných podtried. My si nižšie uvedieme len niektoré z nich. Vymenujme ale metódy, ktoré všetky tieto triedy – potomkovia zdedia. Všetky vymenované metódy môžu vyvolať výnimku typu IOException.

 

 

 

 

 

Metódy znakovo orientovaných prúdov

 

Trieda Reader:
int read()
int read(char[] poleZnakov)
int read(char[] poleZnakov, int index, int pocetZnakov)

 

Trieda Writer:
void write(int i)
void write(char[] poleZnakov)
void write(char[] poleZnakov. int index, int pocetZnakov)

 

Metódy bajtovo orientovaných prúdov

 

Trieda InputStream:
int read()
int read(byte[] poleBajtov)
int read(byter[] poleBajtov, int index, int pocetBajtov)

 

Trieda OutputStream:
void write(int i)
void write(byte[] poleBajtov)
void write(byte[] poleBajtov. int index, int pocetBajtov)

 

 

 

 

 

 

 

 

  Čítanie zo súboru, písanie do súboru

 

  Pozrime sa na príklad čítania a písania po znakoch.  Nasledujúci kód pracuje správne, ak je súbor „Prepisuj.java“  a takisto „text.txt“ v aktuálnom adresári.

 

Kód P8.2

import java.io.*;

public class Prepisuj {

// prepise text zo suboru "text.txt" tak, ze vsetky pismena "y"

// zameni za "i"

    char totoPrepis;

    char prepisNaToto;

       

  public Prepisuj(char zTohto, char naTento){

          totoPrepis = zTohto;

          prepisNaToto = naTento;

  }

     

  public void prepis(File vzor, File ciel){

          try{

                    FileReader citac = new FileReader(vzor);

                     FileWriter pis = new FileWriter(ciel);

                     int c;

                     

                     while(( c = citac.read()) != -1 ){

                              if(c==totoPrepis)

                                pis.write(prepisNaToto);

                              else

                                pis.write(c);

                     }

 citac.close();

  pis.close();

 

          }

          catch(FileNotFoundException fe){

            System.err.println("Nenasiel som subor.");

          }

          catch(IOException e){

                    System.err.println("Chyba pri tvoreni FileWritera.");

          }

     

  }

public static void main(String[] args){

    File vzor = new File("text.txt");

     File ciel = new File("prepisanyText.txt");

    Prepisuj  zmen = new Prepisuj('y', 'i');

                               zmen.prepis(vzor,ciel);

}//EOMain

}//EOClass

 

 

 

Možný výstup:

 

 Ak súbor text.txt existoval v aktuálnom adresári a bol v ňom tento text:

 

Tento nevyznamny text je urceny na to, aby bol prepisany.

 

  Cierny ponik cierni poniklec. Styri psy sa potkli o kly.

 

Jary basnik basni o jari, mozno sa mu aj rym podari.

 

Teraz skúsim písať aj ľščťžýáíé.

 

 

 

Výsledkom programu bolo vytvorenie súboru s názvom „prepisanyText.txt“

 

A s textom:

 

Tento neviznamni text je urceni na to, abi bol prepisani.

 

  Cierni ponik cierni poniklec. Stiri psi sa potkli o kli.

 

Jari basnik basni o jari, mozno sa mu aj rim podari.

 

Teraz skúsim písa? aj ľšč?žýáíé.

 

 

 

Ako vidíme, Java si tu neporadila so všetkými písmenami slovenskej abecedy.Program bol spustený pod verziou Java 1.3. Pri spustení vo verzii 1.4 sa správne zapísal aj znak " ť ". Všimnime si, že metóda „read()“ vracia integer. Ak sa dosiahol koniec prúdu – v tomto prípade koniec súboru – vráti hodnotu –1.  Pozrite si v dokumentácii, s akými argumentami je schopná pracovať metóda „write()“.

Využitie Bufferovania

 

Pre vyspelého čitateľa nie je zrovna ideálne riešenie môcť čítať iba znak po znaku. Aby sme mohli čítať po celých riadkoch, stačí nám už známe objekty typu „FileReader, FileWriter“ obaliť objektami typu „BufferedReader, BufferedWriter“, ktoré majú k dispozícii metódy „readLine()“,  respektíve

„write(String s) “ a „newLine()“. Rozviňme tému z predchádzajúceho príkladu.  Pozrime si prácu programu Cenzor, ktorý z načítaného súboru „list.txt“ vyberie nepovolené slová a nahradí ich jemnejšími.

 

 

 

 

Kód P8.3

import java.io.*;

 

public class Cenzor {

String[] zakazane;

String[] nahradne;

   

public Cenzor(String[] zle, String[] dobre) {

 if(zle.length > dobre.length)

      System.err.println("Cenzor zle vytvoreny.");

      else {

       zakazane = zle;

       nahradne = dobre;     

      }

  }

   

   public void cenzuruj(File f){

     try{

         FileReader fr = new FileReader(f);

         BufferedReader citaj = new BufferedReader(fr);

        

         File scenzurovane = new File("pozdrav.txt");

         scenzurovane.createNewFile();

         BufferedWriter pis = new BufferedWriter(new FileWriter(scenzurovane));

         String s, sc;

         while( (s = citaj.readLine())!= null) {

                   sc = oprav(s);

                   pis.write(sc);

                   pis.newLine();

         }

        

         fr.close();

         pis.close();

     }

     catch(IOException e){

         System.err.println("Sorry, chyba pri cenzure.");

     }

   }

   

public String oprav(String s){

  String sc;

  sc = s;

  // pre kazdy prvok - zakazane slovo nahradi toto slovo povolenym

  for(int j = 0; j < zakazane.length; j++){

          int index;

                    int k = zakazane[j].length();

          while((index =sc.indexOf(zakazane[j])) > -1){

                    // tu zakazane slovo vyreze a nahradi ho nahradnym

                    sc = sc.substring(0,index) + nahradne[j] + sc.substring(index +k);

                   

          }

     

  } //EOFor

  return sc;

}//EOOprav

public static void main(String[] args){

    Cenzor catar = new Cenzor(new String[]{"zle","idiot"}, new String[]{"dobre","sympaticky"});

   File f = new File("list.txt");

   catar.cenzuruj(f);

  }

}

 

 Program sme spustili so súborom „list.txt“ v aktuálnom adresári, ktorý mal tento text:

Mili rodicia,

 

  mam sa tu na vojne velmi zle. Aj nam velmi zle varia.

 Navyse catar je idiot, porucik tiez a snad o ziadnom nadriadenom

 by som nemohol povedat, ze nie je idiot. No, ale vsetkemu zlemu

 je po case koniec. Coskoro budem z tohto idiotskeho prostredia

 zase doma.

  Vas Karol

Program vytvoril súbor „pozdrav.txt“ s textom:

 

Mili rodicia,

 

  mam sa tu na vojne velmi dobre. Aj nam velmi dobre varia.

 Navyse catar je sympaticky, porucik tiez a snad o ziadnom nadriadenom

 by som nemohol povedat, ze nie je sympaticky. No, ale vsetkemu dobremu

 je po case koniec. Coskoro budem z tohto sympatickyskeho prostredia

 zase doma.

  Vas Karol

 

 

Ukladanie objektov. ObjectInputStream, ObjectOutputStream

  Java umožňuje ukladať na disk aj konkrétne inštancie tried, t. j. konkrétne objekty. A to takým spôsobom, aby sa zachovali, aj keď program skončí a aby boli k dispozícii pri ďalších spusteniach tohto programu alebo iných programov. Tento proces sa nazýva serializácia a vykonáva sa prostredníctvom tried ObjectInputStreamObjectOutputStream. Majú okrem iného k dispozícii metódy readObject(), respektíve  writeObject().

Použijeme kód P5.6 Vstup.class dajte do spoločného adresára so súborom Pokec.java, obsahujúcim nasledujúci kód:

Kód P8.4

import java.io.*;

class Besednik  implements Serializable{

   

int vek = -1;

String meno = "?";

Boolean jeMuz = null;

   

public void setVek(int j ){

    vek = j;

  }

   

public Besednik(int vek, String meno, boolean jeMuz){

  this.vek = vek;

  this.meno = meno;

  this.jeMuz = new Boolean(jeMuz);

  } 

   // nasledujuci konstruktor sluzi  pre spolupracu

   // s metodou nacitaj() v triede Pokec

public Besednik(){

this.meno = "Nacitanie prebehlo zle, neviem urcit udaje o Besednikovi";

  }

   

public void setMeno(String name){

    meno = name;

  }

   

public void setPohlavie(String s){

    if(s.equals("ano")) jeMuz = new Boolean(true);

    else {

          if(s.equals("nie")) jeMuz = new Boolean(false);

          else System.err.println("Z tohto udaju neviem urcit pohlavie.");

    }//EOVonkajsieElse

}//EOMethod

    

public String toString(){

  String s = meno; 

    if(jeMuz != null){

    boolean muz = jeMuz.booleanValue();

    if(muz) {

          s += " je muz ";

    }

    else

    {

          s+= " je zena ";

    }

    }

    if(vek != -1){

          s+= " vo veku " + String.valueOf(vek)  + " rokov";

    }

    s+=".";

    return s;

  }

}

 

public class Pokec {

   

public void rozhovor(Besednik bes){

 System.out.println("Napis prosim tvoje meno a stlac enter.");

 bes.setMeno( Vstup.citaj());    

 System.out.println("Napis prosim svoj vek. Cislom.");

 int kolkoRokov = Integer.parseInt(Vstup.citaj());

 bes.setVek(kolkoRokov);        

 System.out.println("Si muz? Odpovedz prosim \"ano\" alebo \"nie\".");

 bes.setPohlavie(Vstup.citaj());

  }

   

// tato metoda vrati objekt Besednik po precitani suboru

        public Besednik nacitaj(File f){

          Besednik vzkrieseny = new Besednik();       

          try{

         FileInputStream in = new FileInputStream(f);

         ObjectInputStream vzkriesObjekt = new ObjectInputStream(in);

         // moze sposobit ClassNotFoundException:

         vzkrieseny = (Besednik)vzkriesObjekt.readObject();

          }

          catch(IOException e){

                    System.err.println("Problemy pri krieseni ulozeneho Besednika.");

          }

          catch(ClassNotFoundException cnf){

                    System.err.println("Zial, Besednici uz neexistuju.");

          }

         return vzkrieseny;

        }

   

   

  public void uloz(Besednik bes){

          File cakaren = new File("cakaren.bin");

          try{

            if(! (cakaren.exists() && cakaren.isFile()) ){

                     cakaren.createNewFile();

             }

          FileOutputStream out = new FileOutputStream(cakaren);

          ObjectOutputStream zapisObjekt = new ObjectOutputStream(out);

          zapisObjekt.writeObject(bes);

          out.close();

          }//EOTry

          catch(IOException e){

            System.err.println("Chyba pri ukladani Besednika");     

          }

  }//EndOfUloz

public static void main(String[] args){

  Pokec skladnik = new Pokec();

 Besednik prvyClovek = new Besednik(0,"Adam",true);  

 // ak uz udaje o osobe existuju, nacitaj ich zo suboru cakaren.bin

  File cakaren = new File("cakaren.bin");

  if(cakaren.exists() && cakaren.isFile()){

    prvyClovek = skladnik.nacitaj(cakaren);  

     System.out.println(prvyClovek);

 

  }

 // ak nie, prvyClovek ostava az do rozhovoru nemeneny

 

// Nacita udaje z klavesnice a nastavi nove hodnoty do objektu Besednik

 skladnik.rozhovor(prvyClovek);

 System.out.println(prvyClovek + "\n Ukladam Besednika pre dalsi beh programu.");

 skladnik.uloz(prvyClovek);

 // objekt Besednik ulozi do suboru cakaren.bin

  }

   

}

 

  Jedna možnosť výpisov z programu:

  Prvý beh programu:

Napis prosim tvoje meno a stlac enter.

Kapitan Nemo

Napis prosim svoj vek. Cislom.

84

Si muz? Odpovedz prosim "ano" alebo "nie".

ano

Kapitan Nemo je muz  vo veku 84 rokov.

 Ukladam Besednika pre dalsi beh programu.

Process Exit...

Druhý beh programu:

Kapitan Nemo je muz  vo veku 84 rokov.

Napis prosim tvoje meno a stisni enter.

Martanka Ovo

Napis prosim svoj vek. Cislom.

564

Si muz? Odpovedz prosim "ano" alebo "nie".

nie

Martanka Ovo je zena  vo veku 564 rokov.

 Ukladam Besednika pre dalsi beh programu.

Process Exit...

 

Cvičenia

Cv8.1

 

a)V kóde P8.1 nahraďte riadok

File nahradny = new File(podadresar,"premenovany.subor");

riadkom

File nahradny = new File("premenovany.subor");

Spustite program znovu. Preskúmajte po jeho zbehnutí aktuálny adresár a jeho podadresár. Čo sa stalo, zmenilo?

 

b) Skúste premenovať adresár „mam“ z cesty C:\Anicka\mam\ta\rad   na „nemam“.

 

Cv8.2

Zvoľte si dostatočne plný adresár - napríklad C:\Program Files. V aktuálnom adresári vytvorte súbor „spion.txt“ . Do tohto súboru vypíšte všetky podadresáre a súbory obsiahnuté vo zvolenom adresári. Pri každom z nich vypíšte aj jeho veľkosť.

 Cv8.3  Vráťte sa znovu ku kódu P5.6. Preskúmajte ho z hľadiska toho, čo už viete o ošetrovaní výnimiek a o metódach vstupu a výstupu. Prerobte tento program tak, aby metóda „read()“ čítala z klávesnice len jednotlivé znaky – pozrite sa v dokumentácii, do akej triedy patrí objekt System.in a aké varianty metódy „read()“ môže používať.

 

Riešenia

 

Cv8.1

 

b) Napriklad takto: Dopíšte na koniec kódu P8.1  riadky:

 

File adresarNaPremenovanie = new File("C:" + s +"Anicka" +s + "mam");

 

File noveMeno = new File("C:" + s +"Anicka" +s + "nemam");

 

adresarNaPremenovanie.renameTo(noveMeno);

 

Spustite kód a sledujte, čo sa stalo.

 

Potom pripíšte ešte jeden riadok:

 

(r1)  adresarNaPremenovanie.delete();

 

Pozrite si dokumentáciu k metóde „delete()“, aby ste rozumeli správaniu sa programu.

 

Nakoniec nahraďte riadok (r1) týmito riadkami:

 

celaCesta.delete();

 

File adresarTa = new File("C:" + s + "Anicka" + s +"mam" + s +"ta");

 

adresarTa.delete();

 

adresarNaPremenovanie.delete();

 

 

 

Najprv posledné tri zakomentujte , spustite program a zistite, čo sa stalo s príslušnými adresármi.

 

Potom vždy odkomentujte jeden riadok a zopakujte procedúru. Až kým nebudú všetky riadky odkomentované.

 

 

home uvod K1 K2 K3 K4 K5 K6 K7 K8 K9 K10 K11 K12 K13 K14

Vaše komentáre: kupka@fmph.uniba.sk