3. diel - Práca s textovými súbormi v Jave
V minulom dieli seriálu tutoriálov pre Javu, Úvod do práce so súbormi v Jave, sme si ukázali,
ako fungujú prístupové práva v operačných systémoch a ako sa vytvárajú
inštancie tried Path
a File
.
V dnešnom Java tutoriále si vysvetlíme prácu s textovými súbormi pomocou staršieho API java.io a novšieho API java.nio.
Najjednoduchšou cestou, ako uložiť dáta aplikácie na pevný disk, je
využiť textové súbory. So súbormi s príponou
.txt
sme sa určite všetci už stretli. Text je v nich uložený
jednoducho na jednotlivých riadkoch. Na oddelenie riadkov sa využívajú
špeciálne znaky, ktoré sú bohužiaľ špecifické pre každý operačný
systém. Toto však za nás našťastie vyrieši Java.
API java.io
Poďme sa najprv pozrieť na starší spôsob práce so súbormi pomocou API java.io.
Zápis do nového textového súboru
Vytvoríme si nový projekt s názvom TextFiles
a v ňom triedu
Main
s obvyklou metódou main()
. Na zápis do
textového súboru slúži trieda FileWriter
, ktorá sa ale obvykle
obaľuje do triedy BufferedWriter
. Objekt
BufferedWriter
používa na zápis na disk vyrovnávaciu
pamäť a je teda výrazne výkonnejší. Tiež poskytuje metódu
newLine()
. Táto metóda vloží do súboru správny znak
konca riadka, nezávisle na operačnom systéme.
Najprv si ale vytvoríme inštanciu triedy File
, tak ako sme si
to ukázali v tejto lekcii.
Súbor pomenujeme napríklad oldapi.txt
.
File file = new File(System.getProperty("user.home") + File.separator + "ictdemy" + File.separator + "oldapi.txt"); file.getParentFile().mkdirs();
Teraz vytvoríme blok try-with-resources
a v ňom novú
inštanciu typu BufferedWriter
. Ako už vieme z predchádzajúcich
dielov, blok try-with-resources
sa nám automaticky postará o
zatvorenie súboru po dokončení zápisu/čítania. Do
konštruktora vložíme inštanciu objektu FileWriter
. Samotný
objekt FileWriter
potrebuje objekt typu File
, ktorý
sme vytvorili vyššie:
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) { } catch (Exception e) { System.out.println("Unable to write to the file."); }
Náš objekt BufferedWriter
je teraz nasmerovaný na správny
súbor. Nový riadok zapíšeme pomocou metódy
write()
. Odriadkovanie v súbore docielime
metódou newLine()
. Po dokončení zápisu musíme zavolať metódu
flush()
, ktorá sa stará o vyprázdnenie bufferu.
S tým sa tu nebudeme zaťažovať, postačí nám vedieť, že nami zapísané
riadky môžu zostať chvíľu vo vyrovnávacej pamäti a my
pomocou flush()
vynútime ich zápis.
Kód sa nám teda rozrástol a vyzerá takto:
File file = new File(System.getProperty("user.home") + File.separator + "ictdemy" + File.separator + "oldapi.txt"); file.getParentFile().mkdirs(); try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) { bw.write("The first line"); bw.newLine(); bw.write("This text is on the second line"); bw.newLine(); bw.write("And the third one"); bw.newLine(); bw.flush(); } catch (Exception e) { System.out.println("Unable to write to the file."); }
Po spustení sa vytvorí súbor oldapi.txt
v našom domovskom
adresári v podadresári ictdemy/
. Môžeme sa tam pozrieť a
bežným textovým editorom sa presvedčiť, že skutočne obsahuje náš
text:
Pripísanie textu do existujúceho súboru
Takto do existujúceho súboru pripíšeme nový riadok:
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true))) { bw.write("An appended line"); bw.newLine(); bw.flush(); } catch (Exception e) { System.out.println("Unable to write to the file."); }
Druhým parametrom konštruktora objektu FileWriter
s hodnotou true
, špecifikujeme pripísanie do existujúceho
súboru, ktorého pôvodný obsah zostane nezmenený.
Čítanie existujúceho súboru
Zostáva nám už len vedieť súbor načítať. Nie je to o
nič zložitejšie, než zápis a opäť k tomu máme v Jave pripravenú triedu,
konkrétne BufferedReader
. Použitie je obdobné, namiesto metódy
write()
použijeme metódu readLine()
, ktorá vracia
riadok textu zo súboru a zároveň sa presunie na nasledujúci
riadok. Budeme ju teda volať v cykle while
. Podmienka pre
ošetrenie vyjdenia zo súboru je možno krkolomnejšia, kontrolujeme, či
prebehlo priradenie nového riadka do premennej.
Kód na výpis obsahu súboru do konzoly vyzerá takto:
try (BufferedReader br = new BufferedReader(new FileReader(file))) { String s; while ((s = br.readLine()) != null) { System.out.println(s); } } catch (Exception e) { System.out.println("Unable to read the file."); }
K jednotlivým akciám doplníme informáciu o úspešnom vykonaní výpisom do konzoly. Kód celého nášho programu potom vyzerá takto:
File file = new File(System.getProperty("user.home") + File.separator + "ictdemy" + File.separator + "oldapi.txt"); file.getParentFile().mkdirs(); // writing to the file try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) { bw.write("The first line"); bw.newLine(); bw.write("This text is on the second line"); bw.newLine(); bw.write("And the third one"); bw.newLine(); bw.flush(); System.out.println("The file has been successfully written."); } catch (Exception e) { System.out.println("Unable to write to the file."); } // appending a text to the file try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true))) { bw.write("An appended line"); bw.newLine(); bw.flush(); System.out.println("A new line has been successfully appended into the file."); } catch (Exception e) { System.out.println("Unable to write to the file."); } // printing the contents of the file System.out.println("Printing file contents:"); try (BufferedReader br = new BufferedReader(new FileReader(file))) { String s; while ((s = br.readLine()) != null) { System.out.println(s); } } catch (Exception e) { System.out.println("Unable to read the file."); }
A výsledok:
Konzolová aplikácia
The file has been successfully written.
A new line has been successfully appended into the file.
Printing file contents:
The first line
This text is on the second line
And the third one
An appended line
Process finished with exit code 0
API java.nio
Teraz sa pozrieme na novší spôsob práce so súbormi pomocou API java.nio.
Zápis do nového textového súboru
Najprv si vytvoríme inštanciu triedy Path
. Súbor pomenujeme
napríklad newapi.txt
:
Path path = Path.of(System.getProperty("user.home"), "ictdemy", "newapi.txt");
Na zápis do súboru použijeme statickú metódu writeString()
z triedy Files
. Nezabudneme najskôr vytvoriť všetky potrebné
adresáre a zachytávať prípadnú výnimku.
Ako oddeľovač riadku použijeme univerzálny oddeľovač pomocou metódy
lineSeparator()
.
Metóda writeString()
prijíma dva a viac parametrov.
Prvý parameter je typu Path
, čiže
súbor, do ktorého chceme zapisovať. Druhý
parameter je typu String
, čiže text, ktorý
chceme zapisovať. Potom nasledujú nepovinné parametre typu
StandardOpenOption
, ktorými metóde hovoríme, akým spôsobom sa
má súbor otvoriť.
Spôsoby otvorenia súboru
Najpoužívanejšie voľby výpočtového typu
StandardOpenOption
pre spôsoby otvorenia súboru
sú tieto:
CREATE
- vytvorí nový súbor, nevyhadzuje chybu, pokiaľ už existuje.CREATE_NEW
- vytvorí nový súbor, vyhodí chybu, ak súbor už existuje.TRUNCATE_EXISTING
- pri otvorení vymaže obsah súboru.APPEND
- otvorí súbor na pridávanie obsahu.
V nasledujúcom príklade pri zápise prvého riadka použijeme voľbu
CREATE
a TRUNCATE_EXISTING
, aby sa súbor vytvoril a
existujúci súbor najprv vymazal. Každý ďalší zápis už robíme pomocou
voľby APPEND
, aby sa zapisovaný text typu String
pridal na koniec súboru:
try { Files.createDirectories(path.getParent()); Files.writeString(path, "The first line" + System.lineSeparator(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); Files.writeString(path, "This text is on the second line" + System.lineSeparator(), StandardOpenOption.APPEND); Files.writeString(path, "And the third one" + System.lineSeparator(), StandardOpenOption.APPEND); } catch (IOException ex) { System.out.println("Unable to write to the file: " + ex.getMessage()); }
Rovnako ako v prípade staršieho API java.io,
sa nám aj teraz po spustení programu vytvorí nový súbor s
názvom newapi.txt
obsahujúci tri riadky textu.
Môžeme si to overiť ľubovoľným textovým editorom.
Pripísanie textu do existujúceho súboru
Pripísanie riadkov do už existujúceho súboru robíme pomocou voľby
APPEND
:
try { Files.writeString(path, "This text is on the last line" + System.lineSeparator(), StandardOpenOption.APPEND); } catch (IOException ex) { System.out.println("Unable to write to the file: " + ex.getMessage()); }
Čítanie existujúceho súboru
Na čítanie riadkov z textového súboru použijeme metódu
readAllLines()
opäť z triedy Files
. Táto metóda
vracia kolekciu List<String>
:
try { List<String> lines = Files.readAllLines(path); lines.forEach(System.out::println); } catch (IOException ex) { System.out.println("Unable to read the file: " + ex.getMessage()); }
V nasledujúcom kvíze, Kvíz - Základy práce so súbormi a výnimkami v Jave, si vyskúšame nadobudnuté skúsenosti z predchádzajúcich lekcií.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 0x (2.44 kB)
Aplikácia je vrátane zdrojových kódov v jazyku Java