Cvičenia: 7. týždeň

Cieľom cvičení siedmeho týždňa je vyskúšať si prácu s výnimkami a textovými súbormi.

Výnimky

  • Diskutujte, čo sú výnimky a na čo slúžia.
  • Na čo slúži metóda Integer.parseInt? Nájdite v dokumentácii, akú behovú výnimku môže hodiť?
  • Vytvorte triedu MojaKorytnacka, ktorá rozšíruje triedu Turtle. Do triedy MojaKorytnacka pridajte metódu retazecNaCislo, ktorá transformuje znakový reťazec na číslo. Ak transformácia nevyjde (napr. reťazec nie je číselným reťazcom), metóda nech vráti hodnotu zadanú parametrom defaultnaHodnota.
public int retazecNaCislo(String s, int defaultnaHodnota)

Práca so súbormi v adresároch

  • Na čo slúžia objekty triedy File (java.io.File)?

Vytvorte triedu TurtleCommander, ktorá rozširuje triedu Turtle. Pri všetkách nasledujúcich metódach uvažujeme len súbory priamo v zadanom adresári, t.j. nie v podadresároch. Keďže ObjectInspector nepodporuje volanie metód, kde niektorý z parametrov je referencia na objekt triedy File, na overenie toho, či sme naprogramovali metódy správne, budeme testovacie "príkazy" písať do metódy main v "spúšťači".

  • Pridajte do triedy TurtleCommander metódu, ktorá vypíše názvy všetkých súborov a adresárov v zadanom adresári:
public void vypisAdresar(File adresar);
  • Pridajte do triedy TurtleCommander metódu, ktorá vráti počet súborov (nie adresárov) v zadanom adresári:
public int pocetSuborov(File adresar);
  • Pridajte do triedy TurtleCommander metódu, ktorá vráti súčet veľkosti súborov (nie adresárov) v zadanom adresári:
public long velkostSuborovVAdresari(File adresar);
  • Pridajte do triedy TurtleCommander metódu, ktorá overí, či sa v oboch zadaných adresároch nachádza nejaký súbor (pozor, nie adresár) s rovnakým menom:
public boolean suborSRovnakymMenom(File adresar1, File adresar2)

Tresty

  • Do triedy TurtleCommander pridajte metódu trest, ktorá do zadaného súboru vypíše reťazec zadaný počet krát:
public void trest(File suborNaTrest, String trestnaSprava, int pocet)
Príklad použitia:
File subor = new File("trest.txt");
studentUPJS.trest(subor, "Student chodi na cvicenia vzdy pripraveny!", 100);
  • Kde sa vytvorí súbor trest.txt?
  • Otvorte vytvorený súbor v textovom editore.
  • Porovnajte veľkosť vytvoreného súboru s počtom zapisovaných znakov.
  • Otvorte vytvorený textový súbor ako binárny súbor.

Kódy znakov

  • Do triedy TurtleCommander pridajte metódu unicodeKody, ktorá do zadaného súboru vypíše znaky a ich kódy. Vypíšte iba znaky, ktorých kódy sú zo zadaného intervalu.
public void unicodeKody(File suborNaTrest, int odKodu, int poKod)

Záznam kliknutí

Vytvorte triedu KlikaciaPlocha, ktorá bude rozširovať triedu WinPane. Klikacia plocha nech funguje tak, že pri kliknutí do plochy sa mieste kliknutia nakreslí bodka náhodného polomeru medzi 2 až 5. Do triedy KlikaciaPlocha pridajte metódu ulozKlikyDoSuboru, ktorá ako parameter dostane názov súboru (alebo referenciu na objekt triedy File s názvom súboru). Táto metóda nech uloží do zadaného súboru informácie o všetkých nakreslených bodkách od vytvorenia plochy. Informácia o jednej bodke nech je v jednom riadku súboru a skladá sa z 3 čísel: x-ová súradnica stredu bodky, y-ová súradnica stredu bodky a polomer bodky.

Môžete predpokladať, že nikdy sa nespraví viac ako 1000 bodiek od vytvorenia kresliacej plochy (t.j. nemeňte veľkosť poľa po každom kliknutí).

public void ulozKlikyDoSuboru(String subor)
// alebo
public void ulozKlikyDoSuboru(File subor)

Príklad súboru:

100 121 3.5
10 252 2.5
241 139 4.0

Do triedy KlikaciaPlocha pridajte "protimetódu", ktorá na základe obsahu textového súboru s vyššie opísaným formátom nakreslí do kresliacej plochy v ňom uložené bodky.

Upozornenie: Ak chcete použiť ObjectInspector na zavolanie metód objektov triedy KlikaciaPlocha pracujúcich so súbormi, musíte použiť verziu s parametrami typu String.

Analýza súborov

Vytvorte triedu Analyzatorka, ktorá rozširuje triedu Turtle a ktorá bude poskytovať základné spracovanie textových súborov.

  • Priemer čísel: Pridajte do triedy Analyzatorka metódu, ktorá ako parameter dostane názov súboru (prípadne referenciu na objekt triedy File). V tomto súbore sú len celé čísla oddelené medzerami (v jednom riadku môže byť aj viacero čísel). Vytvorená metóda nech vráti priemer čísel v súbore.
public double priemer(String subor)
// alebo
public double priemer(File subor)
  • Počet riadkov: Pridajte do triedy Analyzatorka metódu, ktorá ako parameter dostane názov súboru (prípadne referenciu na objekt triedy File). Vytvorená metóda nech vráti počet riadkov v súbore.
public int pocetRiadkov(String subor)
// alebo
public int pocetRiadkov(File subor)

Riadená korytnačka

Vytvorte triedu RiadenaKorytnacka, ktorá bude rozširovať triedu Turtle. Do triedy RiadenaKorytnacka pridajte metódu podlaSuboru. Táto metóda dostane ako parameter názov (resp. cestu k) súboru s príkazmi pre korytnačku. Na cvičení stačí, ak naprogramujete vykonanie aspoň jedného príkazu bez parametrov a aspoň jedného príkazu s parametrami.

public void podlaSuboru(String subor)

Pre obsah súboru s príkazmi platia tieto pravidlá:

  • v každom riadku je jeden príkaz
  • každý príkaz začína svojim názvom a je nasledovaný parametrami (reálne čísla)
  • v súbore môžu byť tieto príkazy:
    • center
    • penDown
    • penUp
    • step (1 parameter)
    • turn (1 parameter)
    • dot (1 parameter)
    • setPosition (2 parametre)
    • moveTo (2 parametre)

Príklad vstupného súboru:

setPosition 100 170
step 100
turn 120
dot 5
step 100
turn 120
dot 5
step 100
turn 120
dot 5

Rada: Vytvorte si pomocnú metódu, ktorá dostane ako parameter jeden riadok súboru (jeden príkaz) a vykoná príkaz v tomto riadku. Na spracovanie riadka použite Scanner znakového reťazca.

public void vykonajPrikaz(String celyPrikaz)

Pre fajnšmekrov: vymyslite taký formát vstupného súboru, aby umožňoval zopakovať nejakú postupnosť príkazov zadaný počet krát (niečo ako for-cyklus s pevným počtom opakovaní).

Doležitá poznámka o bodkách a čiarkach

Pri načítavaní čísel s desatinnou časťou sa môže ukázať na počítačoch so slovenskou lokalizáciou problém. Scanner môže byť "zmätený" z toho, že sa na vstupe objaví číslo, ktoré namiesto "slovenskej" desatinnej čiarky (3,14) obsahuje "americkú" desatinnú bodku (3.14). Poznamenajme, že pri zapisovaní čísel s desatinnou časťou do súborov ich PrintWriter zapíše s desatinnou bodkou (nie čiarkou). Aby sme tento problém vyriešili, dohodnime sa, že pred načítavaním čísel s desatinnou časťou cez Scanner (metóda nextDouble, resp. hasNextDouble) zmeníme "lokalizačné" nastavenia pre Scanner zavolaním metódy useLocale:

citac.useLocale(Locale.US);

Toto "lokalizačné" nastavenie povie Scanner-u, že má čísla s desatinnou časťou čítať "po americky", teda ako oddeľovač desatinnej časti čísla sa očakáva bodka.

Ako súčasne čítať a zapisovať

Niekedy je potrebné súčasne čítať jeden súbor a zapisovať do iného súboru. Na túto činnosť môžeme použiť takúto schému:

Scanner citac = null;
PrintWriter zapisovac = null;
try {
        citac = new Scanner(...);
        zapisovac = new PrintWriter(...);
        // pracujeme s citacom a zapisovacom           
} catch (FileNotFoundException e) {
        e.printStackTrace();
} finally {
        if (citac != null) {
                try {
                        citac.close();
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }

        if (zapisovac != null) {
                try {
                        zapisovac.close();
                } catch (Exception e) {
                        e.printStackTrace();
                }
        }
}

Novinky v Java 7

Java 7 priniesla (okrem mnohých iných vecí) aj novinku vo forme try príkazov s manažovaním zdrojov. Z hľadiska programátora to znamená, že nemusí písať finally blok, v ktorom zatvorí otvorené zdroje, resp. súbory (PrintWriter, Scanner, ...) - zatvorenie sa uskutoční automaticky.

Príklad čítania textového súboru v Jave 7:

try (Scanner citac = new Scanner(new File(...))) {
        // pracujeme s citacom
} catch (FileNotFoundException e) {
        e.printStackTrace();
}

Príklad čítania a zapisovania textového súboru v Jave 7:

try (Scanner citac = new Scanner(new File(...)); PrintWriter zapisovac = new PrintWriter(new File(...))) {
        // pracujeme s citacom a zapisovacom
} catch (FileNotFoundException e) {
        e.printStackTrace();
}

Visual Scanner

Pri prvých krokoch so Scannerom môže pomôcť knižnica VisualScanner: VisualScanner.jar