Datoteke - uporaba razredov in metod v javi

Datoteke - uporaba razredov in metod v javi

Avtor: Svetlana Novak

Učni cilji: Dijak se nauči uporabljati funkcije in metode za delo z datotekami v programskem jeziku java.

Datoteke - uvod

Potrebno predznanje:

  • kaj so datoteke in delo z datotekami v operacijskem sistemu
  • kaj so nizi
  • seznami in metode za delo s seznami
  • metoda split()
  • vključevanje modulov v program (import)
  • metode: ustvarjanje novih in klicanje

Datoteke - uvod

Uvod

Datoteke uporabimo, kadar želimo pomniti podatke, da bodo dostopni za kasnejšo uporabo. V gradivu bomo govorili o tekstovnih datotekah, v katerih je vsebina razdeljena v vrstice in branje iz in pisanje v zaporedno. Delo z datotekami je podobno delu z vhodno/izhodnimi tokovi, pri katerih pišemo/beremo na strandardne vhode/izhode kot sta tipkovnica za vhod in prikaz na ekran kot izhod. Pri datotekah pa govorimo o branju/pisanju iz/v datoteke. Java ima vgrajene razrede za delo s tokovi in vsebujejo metode, ki omogočajo rokovanje z vsebino datoteke:

  • uporaba razredov FileReader, FileWriter, File za povezavo do datoteke
  • read(), readLine() - iz razreda BufferedReader za branje podatkov s toka
  • println() - iz razreda PrintWriter za pisanje na tok
  • close()

Naloga: primerjaj vpisovanje v spremenljivko preko tipkovnice in branje iz datoteke ter prikazovanje na ekran s pisanjem v datoteko.

Delo z vhodnimi in izhodnimi tokovi

Napišite ukaz, pri katerih na začetku vpišete niz, ki predstavlja EMŠO. Izpišite ga v obratnem vrstnem redu.

Rešitev:


emso = JOptionPane.showInputDialog("Vpišite EMŠO osebe: "); //vpis podatka

for(int i=emso.length()-1; i >= 0; i--)
   System.out.print(emso.charAt(i));    //prikaži emšo v obratnem vrstnem redu

Primer (EMŠO številka je izmišljena in brez preverjanja veljavnosti):

emso = JOptionPane.showInputDialog("Vpišite EMŠO osebe: ");

Vpišite EMŠO osebe: 12123456789

98765432121

Delo z datotekami

Napišite ukaz, pri katerih na začetku prebereš iz datoteke niz, ki predstavlja EMŠO. Zapišite ga v drugo datoteko v obratnem vrstnem redu.

Rešitev:

(Slika1.PNG)
Slika 1: Delo z datotekami.




Vpisovanje podatkov je podobna metodi readLine() (obe vrneta niz), println() v PrintWriter-ju pa je podoben println() v System.out.

Datoteke - odpiranje in zapiranje datoteke

V javi je uveden nov tip razredov, ki mu pravimo File. File odpremo, da lahko beremo iz obstoječe datoteke oz. da v njo pišemo. Datoteke po uporabi tudi zapremo.

Odpiranje datotek

Datoteke odpiramo na več načinov:


A. odpri datoteko za branje

V spodnjem primeru so naslednji deli ukaza za odpiranje:

  • uporaba razreda za datotečni tok FileReader za branje
  • tok za branje BufferedReader
  • dat - logična oznaka datoteke
  • datoteka.txt - ime fizične datoteke v trenutni mapi programa


BuferredReader dat = new BufferedReader(new FileReader("datoteka.txt"));

V tem primeru je pisanje v datoteko nemogoče. Datoteka mora pred odpiranjem obstajati, sicer se izpiše napaka.

(Slika2.PNG)
Slika 2: Datoteka 'datoteka.txt' ne obstaja.




B. odpri datoteko za pisanje

V spodnjem primeru so naslednji deli ukaza za odpiranje:

  • uporaba razreda za datotečni tok FileWriter za pisanje
  • tok za pisanje PrintWriter
  • dat - logična oznaka datoteke
  • datoteka.txt - ime fizične datoteke v trenutni mapi programa
  •  "true"  - oznaka za pisanje na konec datoteke


PrintWriter dat = new PrintWriter(new FileWriter("datoteka.txt"));

Pri odpiranju datoteke za pisanje brez drugega parametra odpremo prazno datoteko. Pozor: če datoteka že obstaja, se vsi podatki pri tem načinu odpiranja datoteke iz datoteke izbrišejo, če pa datoteke ni, se ustvari nova.


C. odpri datoteko za dodajanje vsebine v datoteko

V spodnjem primeru so naslednji deli ukaza za odpiranje:

  • ostalo glej pisanje
  •  "true"  - oznaka za pisanje na konec datoteke


PrintWriter dat = new PrintWriter(new FileWriter("datoteka.txt", true));

Pri odpiranju datoteke za pisanje z vrednostjo drugega parametra true odpremo datoteko, ki že vsebuje podatke, ki jih ne želimo izbrisati.

Opomba: Pri odpiranju datoteke za branje oz. dodajanje v datoteko mora datoteka obstajati, sicer se izpiše napaka.
Ime fizične datoteke pri vseh treh načinih odpiranja lahko vsebuje tudi pot, ki jo uporabimo pred imenom. Za ločevanje map in podmap se uporablja poševnica nazaj, v nizih v javi pa moramo pred njo napisati še eno poševnico nazaj (glej nize in posebne znake), ali poševnica. Tako v primeru, da ne beremo iz iste mape, v kateri je program, dodamo še pot:

PrintWriter dat = new PrintWriter(new FileWriter("c:\\temp\\ddatoteka.txt", true));


Datoteke - odpiranje in zapiranje datoteke

Zapiranje datotek

Podatkovni tok branja ali pisanja v datoteke po uporabi zapremo. S tem se nam podatki tudi fizično zapišejo v datoteko na disku. Zapiramo vse odprte datoteke ne glede na način odpiranje (branje, pisanje, dodajanje).

Primer: prepiši vsebino datoteke v drugo datoteko. Ukaza readLine() in println() sta razložena v nadaljevanju gradiva.

(Slika3.PNG)
Slika 3: Zapiranje datotek po uporabi.

Datoteke - obstoj

V primerih, ko smo datoteko odpirali za branje oz. dodajanje vsebine, prejmemo sporočilo, če datoteka ne obstaja in se nam program prekine. Z uporabo razreda java.io.File , ki ga vključimo na začetku programa, omogočimo preverjanje obstoja datotek, imenikov, ki jih lahko tudi kreiramo oz. brišemo. Uporabimo lahko naslednje metode za mape in datoteke:


File file = new File("emso.dat");
File mapa = new File("emso");

  •  mapa.mkdir();   // ustvari mapo pot
  •  file.renameTo(new File("nova.dat")); // preimenuj, a napiši v kaj - ciljno ime
  •  boolean del = mapa.delete(); // odstrani mapo pot 
  •  long dol = file.length(); // velikost mape pot
  •  String pot = file.getAbsolutePath(); - pot do datoteke

Naloga: Ustvarite datoteko, če je ni.

Rešitev:

Rešitev

Neki

Ustvarite datoteko, če je ni.

Rešitev:

Z metodo file.exists() && file.isFile() ugotovimo, če datoteka z logičnim imenom file skupaj s pripadajočo potjo, obstaja.

(Slika5.PNG)
Slika 4: Odpri datoteko za dodajanje (true), če obstaja, in novo brez drugega parametra, če je ni.

Zapri


Datoteke - pisanje na datoteko

Pisanje z metodo println()

Za pisanje lahko uporabimo tudi ukaz println() iz razreda PrintWriter za pisanje in z uporabo toka FileWriter:



PrintWriter datZaPisanje = new PrintWriter(new FileWriter("datPisi.txt"));
datZaPisanje.println("Zapišimo še to!");

Primer: zapiši dve vrsti besedila in nato števila med 1 in 10 vsako v svojo vrsto. Uporabite metodo println().

(Slika7.PNG)
Slika 5: Pisanje v datoteko z metodo println().

Datoteke - dodajanje vsebine

Z odpiranjem izhodnega toka za datoteko FileWriter brez drugega parametra ustvarimo novo datoteko. Kaj pa če so v datoteki že podatki in jih nočemo izgubiti? Potem datoteko odpremo s tokom z vrednostjo drugega parametra true , kar pomeni dodaj (append). Nove vsebine se dodajo na konec datoteke.

Datoteka mora pred odpiranjem obstajati.

Uporaba: dodajanje vsebine

Datoteke - branje


Odpiranje datoteke za branje
Pri branju datotek odpremo tok datoteke z razredom FileReader in razredom za branje BufferedReader.



BufferedReader dat1 = new BufferedReader(new FileReader("beri1.dat"));
BufferedReader dat2 = new BufferedReader(new FileReader("c:\\temp\\dobro\\beri2.dat"));

V zgornji kodi moramo, ko dodajamo poševnico nazaj za ločevanje map in podmap, v katerih se datoteka nahaja, dodati še eno poševnico nazaj '\', ker je to poseben znak, ki potrebuje pred seboj še eno poševnico nazaj, da se pot pravilno upošteva.

Opomba: hkrati ne moremo brati in pisati v datoteko z izbranimi razredi. Za to obstajajo drugi razredi.

Metode za branje

readLine()

  • za branje tekoče vrstice z znakom za konec vrstice
  • za ugotavljanje konca datoteke



if (!datoteka.ready())
    System.out.println("Konec datoteke.");

Vendar:



String c = datoteka.readLine();
if (c.length()==0){
    System.out.println("Prazna vrsta");
}



read()

  • za branje znak po znak (kot celo število), dokler ne pridemo do konca datoteke



int znak = datoteka.read();

while(znak != -1) {
    System.out.print((char)znak);
    znak=datoteka.read();
}

Datoteke - branje: zgled



Naloga: prepiši celo datoteko in pred vsako vrstico napiši število znakov vrstice

(Slika12.PNG)
Slika 6: Uporaba readLine().

Datoteke - koristne metode

Pretvorba v števila

Metoda branja readline() vrne niz vrstica.

Uporaba funkcij za pretvorbo v števila:

  • c_stevilo = Integer.parseInt(vrstica);  //celo število
  • f_stevilo = Float.parseFloat(vrstica);  //decimalno število float

Pretvorbo lahko delamo, če je v posamezni vrstici samo število.

Pri pretvorbi int in float ne motijo "beli presledki" (znaki za konec vrstice, presledki, tabulatorji):

//pretvori število v vrstici v celo število
c_stevilo = Integer.parseInt(beriDat.readLine());



Ločevanje podatkov v vrsticah, združevanje v nize

Ko je v vrsticah več kot en podatek, jih ločimo med seboj. Uporabimo metodo split nad vrstico. Ločilni znak je lahko poljuben. Metoda vrne seznam nizov, ki jih po potrebi spremenimo v števila, če jih npr. želimo sešteti. Za ločevanje podatkov se lahko uporabljata razreda Scanner (pretvarja v potrebni tip) in StringTokenizer (loči nize med seboj, ki imajo med seboj napisane različne ločilne znake - delimeterje).



// odpri bralno datoteko
BufferedReader datBeri = new BufferedReader(new FileReader(imeVhod));

String vrstica = datBeri.readLine();
String seznam [] = vrstica.split(" ");  // v seznam daj besede, ločilo je presledek

String skupaj = "";    // String.join v tej verziji jave ne dela
for(String beseda : seznam){
    skupaj += (beseda + ",");
}


Znebimo se dodatkov

Z metodo replaceAll() ali trim() odstranimo znak na koncu vrstice (desno slačenje) oz. odstranimo bele presledke (znak za konec vrstice, presledke, tabulatorje).



BufferedReader datBeri = new BufferedReader(new FileReader(imeVhod));

String vrstica = datBeri.readLine();
//odstrani znak za konec vrstice, spremembo shrani v isto spremenljivko
vrstica=vrstica.trim();
String seznam [] = vrstica.split(" ");  // v seznam daj besede, ločilo je presledek

String skupaj = "";    // String.join v tej verziji jave ne dela
for(String beseda : seznam){
    skupaj += (beseda + ",");
}

Zgled: zgornje metode trim, split in združevanje nizov so uporabljene pri filmčku za dodajanje vsebine.

(Slika11a.PNG) (Slika11b.PNG)
(Slika11c.PNG)
Slika 7: Koda z metodami trim, split in sestavljanje pri datotekah.

Datoteke - branje preko vseh vrstic

Branje preko vseh vrstic:

  • v zanki while


vrstica = datBeri.readline();
while (vrstica != null) {
   // nekaj naredimo z vrstico …

   vrstica = datBeri.readline();
}

  • v zanki while 2


while (vrstica = datBeri.readline() != null) {
   // nekaj naredimo z vrstico …

   vrstica = datBeri.readline();
}
datBeri.close();


  • v zanki while 3


while(datBeri.ready()) {

   //nekaj naredimo z vrstico …

   vrstica = datBeri.readline();
}
datBeri.close();

Datoteke: vprašanje 1

Kaj izvede naslednje zaporedje ukazov?


PrintWriter tuPisem = new PrintWriter(new FileWriter("Podatki.txt"));

for (int i=1; i <= 100; i++) {

    tuPisem.println(i + ". vrstica")

}

tuPisem.Close()

Izberite pravilni odgovor.

Preveri

Pravilno

Dobro poznaš delo z datotekami.

Naprej

Napačno

Mogoče še nekaj časa posvetiš teoriji? Poskusi še enkrat. Saj bo šlo.

Zapri

Datoteke: vprašanje 2

Za sledečo kodo

vrstica = datBeri.readline();

while(datBeri.ready()) {
    //nekaj naredimo z vrstico
    vrstica = datBeri.readLine();
}


izberite med spodnjimi odgovori pravilni odgovor, kaj pomeni pogoj v while stavku.

Izberite pravilni odgovor.

ni konca datoteke
spremenljivka vrstica je prazna
datoteka je prazna
konec datoteke

Pravilno

Čestitam. Le tako naprej.

Naprej

Napačno

Malo je zmanjkalo. Ne obupajte. Poskusite še enkrat.

Zapri

Datoteke: vprašanje 3

Za odpiranje datotek obstaja nekaj načinov. Kako odpremo datoteko za branje? Izberite pravilni odgovor.

Preveri

Pravilno

Poiskali ste vse pravilne odgovore. Odlično. Kviz je zaključen.

Naprej

Napačno

Odgovor ni najboljši. Prosim, potrudite se še malo.

Zapri

Datoteke: primer uporabe - naključna števila

Naloga:

Sestavite metodo, ki ustvari datoteko NakStevX.dat z n naključnimi števili med a in b. X naj bo prvo "prosto" naravno število. Če torej obstajajo datoteke NakStev1.dat, NakStev2.dat in NakStev3.dat, naj metoda ustvari datoteko NakStev4.dat. Števila izpišite levo poravnana po k v vsaki vrsti, torej npr. kot:

12 134 23 22 78 167 12 1 134 45 13 9


Postopek reševanja Najprej z uporabo razreda File in z izdelavo seznama datotek poiščemo zadnjo datoteko NakStevX.dat, kjer je X število. Zadnjo datoteko poiščemo z izločanjem števila X iz imena datotek. Nato v novo datoteko vpišemo n naključnih števil med a in b po k v vsako vrsto. Števila so v datoteki med seboj ločena s presledkom. V prvi metodi tako kreiram novo datoteko, v drugi, ki sprejme vrednosti obeh meja števil a in b, vrednost vseh števil v datoteki in število števil v vrsti k, pa izpišem seznam n naključnih števil po k v vrsti.

Prva metoda (poisciDatoteko):

  • Parametra metode sta dva niza: začetek imena datoteke in končnica datoteke.
  • V zanki poiščemo naslednjo datoteko po vrsti, glede na začetek imena in zaporedne številke ter končnice.
  • Metoda vrne ime naslednje prazne datoteke.

Druga metoda (nakljucnaStevila):

  • Parameter metode je začetek imena datoteke in končnica datoteke, spodnja in zgornja meja števil, število vseh števil v datoteki in število števil v eni vrsti.
  • Odpremo novo datoteko, ki smo jo našli s prvo metodo. Odpremo jo za pisanje - odpri prazno datoteko za pisanje.
  • Nastavimo zanko, v kateri vpišemo n števil v odprto datoteko. Števila ustvarimo z metodo za naključna števila Math.random() in sicer med številoma a in b. Števila zapisujemo po vrsti, med njimi so presledki. V posamezni vrsti je k števil. V zadnji jih je lahko manj in sicer toliko, koliko je ostanek pri deljenju s k.
  • Ob koncu programa zapremo datoteko.

Rešitev:

(Slika13a.PNG) (Slika13b.PNG)
(Slika13c.PNG)
Slika 9: Zapis naključnih števil v datoteko
0%
0%