2. diel - Triedy pre prácu so súbormi v Kotlin
V minulom dieli nášho Kotlin tutoriálu, Použitie výnimiek pri práci so súbormi v Kotlin , sme si vysvetlili výnimky, ktoré k práci so súbormi nutne potrebujeme, pretože vďaka nim môžeme reagovať na prípadné chyby.
V dnešnom Kotline tutoriále si uvedieme jednotlivé typy súborov a triedy pre prácu s nimi. Pozrieme sa na práva na zápis na moderných operačných systémoch. Tiež si ukážeme tvorbu zástupného objektu pre súbor, s ktorým chceme pracovať.
Možnosti ukladania a načítania dát
Dáta, resp. objekty uložené v pamäti, sa samozrejme s vypnutím aplikácie stratia. Ak chceme zaistiť, aby dáta boli perzistentné (trvalé), musíme ich pri ukončení programu uložiť a pri načítaní programu opäť načítať. Na ukladanie dát existuje mnoho spôsobov, každý má svoje výhody a nevýhody.
Dáta našej aplikácie môžeme ukladať nasledujúcimi spôsobmi:
- Textové súbory s jednoduchou štruktúrou (napr.
.txt
a.csv
). - Textové súbory s vnútornou hierarchiou (napr.
.xml
alebo.json
). - Súbory binárneho typu (odtlačok pamäte do súboru).
- Databáza.
- Staršie
java.io.*
, ktorého stredobodom je triedaFile
- novšie a
java.nio.*
, ktoré sa točia okolo triedPath
aFiles
.
Kotlín uprednostňuje použitie triedy Path
, pre
ktorú implementoval balíček kotlin.io.path.*
. Zodpovedajúce API
je vždy potrebné do projektu importovať. Pokiaľ používate rozumné IDE,
samo vás na to upozorní a importy ponúkne a doplní.
V našom kurze sa budeme zameriavať na nové API, ale miestami si ukážeme, ako by sa daná vec robila pomocou staršieho API.
Práva na zápis na disk
Všetky moderné operačné systémy majú nejaký systém prístupových práv k súborom uloženým na disku. Bežný užívateľ má obvykle právo vytvoriť súbory a zapisovať do súborov iba vo svojom domovskom adresári. Administrátor môže zapisovať kamkoľvek.
Pokiaľ v našej aplikácii zakladáme súbory, musíme ich založiť tam, kde má užívateľ právo zapisovať.
V reálnej aplikácii sa používateľa najskôr spýtame,
kde chce nový súbor vytvoriť. Potom skontrolujeme, či môže do danej
lokácie zapisovať. V našich lekciách, v záujme jednoduchosti, tento krok
preskočíme. Všetky súbory budeme zakladať v podadresári
itnetwork\
v domovskom adresári užívateľa.
Domovský adresár používateľa
Domovský adresár užívateľa sa nachádza v každom systéme na inom mieste. Keďže sa snažíme tvoriť multiplatformné aplikácie, vyhneme sa špecifickým cestám k súborom v jednotlivých operačných systémoch.
Domovský adresár používateľa zistíme týmto kódom:
System.getProperty("user.home")
Pozrime sa, aký dostaneme výstup v jednotlivých systémoch, pokiaľ ho necháme vypísať:
Windows systémy
V systémoch Windows vyššie uvedený kód vráti:
C:\Users\vase_jmeno\
Všimnime si oddeľovače adresárov \
, ktorým je
spätná lomka. Ako uvidíme nižšie, ostatné operačné
systémy používajú pre oddeľovač adresárov lomítko
dopredu /
. Windows sú tiež špecifické v označovaní
diskov písmenami (C
, D
...).
Linux systémy
V systémoch Linux vyššie uvedený kód vráti:
/home/vase_jmeno/
MacOS systém
V systéme MacOS vyššie uvedený kód vráti:
/Users/vase_jmeno
Vytvorenie Path
z API kotlin.io.path.Path
Základom úspešnej práce so súbormi v Kotline je mať správne vytvorenú
inštanciu triedy Path
(pri použití novšieho
API), alebo File
(pri použití staršieho API). Tá reprezentuje
cestu k súboru, s ktorým chceme pracovať. Čítanie súboru,
alebo zápis do súboru potom prebieha za pomoci tejto
inštancie.
Poďme sa teda najprv pozrieť na to, ako správne vytvoriť inštanciu
triedy Path
:
val cesta = Path(cesta_k_souboru)
Príklad
Napríklad cestu k súboru soubor.txt
, v podadresári
itnetwork\
, v našom domovskom adresári definujeme takto:
val cesta = Path(System.getProperty("user.home"), "itnetwork", "soubor.txt")
V kóde neriešime špecifické cesty k súboru pre jednotlivé
operačné systémy. Vďaka System.getProperty()
získame správnu
cestu pre platformu, na ktorej je aplikácia spustená.
Inštancia triedy Path
je ukazovateľ na miesto na
disku, kde môže, ale nemusí daný súbor byť. Taktiež nemusí
existovať všetky adresáre v ceste k súboru. Napríklad v našom príklade je
možné, že ešte nemáme v našom domovskom adresári adresár
itnetwork\
.
Kontrola adresárov
Poďme sa teda najprv uistiť, že všetky potrebné adresáre naozaj
existujú a prípadne ich vytvoriť. Na tento účel slúži statická
metóda createDirectories()
z triedy
Files
:
val cesta = Path(System.getProperty("user.home"), "itnetwork", "soubor.txt") Files.createDirectories(cesta.parent)
Metóda parent
vracia adresár, v ktorom sa nachádza
soubor.txt
. V našom príklade je to adresár
itnetwork\
. Metóda createDirectories()
vytvorí celú
potrebnú hierarchiu adresárov vrátane itnetwork\
.
Pokiaľ by niektorý adresár už existoval, metóda
createDirectories()
vytvorenie adresára preskočí bez vyvolania
výnimky. Preto je vhodné ju použiť pri každom definovaní cesty k
súboru.
Vytvorenie File
zo staršieho API java.io.*
Pri použití staršieho API pracujeme s triedou File
.
Vytvorenie samotnej inštancie je tu veľmi podobné. Na rozdiel od triedy
Path
, trieda File
očakáva cestu k súboru ako jeden
String
:
val cesta = File("cesta_k_souboru")
Príklad
Rovnako ako v prípade Path
, aj tu môžeme využiť
System.getProperty()
na získanie cesty k domovskému
adresáru. Našu cestu k súboru soubor.txt
, v
podadresári itnetwork\
, v našom domovskom adresári tu definujeme
takto:
val cesta = File(System.getProperty("user.home") + File.separator + "itnetwork" + File.separator + "soubor.txt")
Pomocou File.separator
vytvoríme platnú cestu
pre akúkoľvek platformu.
Kontrola adresárov
Rovnako ako v prípade Path
aj teraz potrebujeme skontrolovať,
či existujú všetky definované adresáre. Na to využijeme
metódu mkdirs()
spolu s metódou parentFile
, ktorá
určuje nadradený adresár. Metódy tentoraz zavoláme na inštanciu triedy
File
:
val cesta = File(System.getProperty("user.home") + File.separator + "itnetwork" + File.separator + "soubor.txt") cesta.parentFile.mkdirs()
Prevediteľnosť Path
<->
File
Triedy Path
a File
ponúka jednoduchú konverziu
medzi sebou.
Konverzia Path
na
File
Pre prevedenie cesty k súboru z inštancie triedy Path
na
inštanciu triedy File
, zavoláme metódu toFile()
na
inštanciu triedy Path
:
val path = Path(System.getProperty("user.home"), "itnetwork", "soubor.txt") val file = path.toFile()
Konverzia File
na
Path
Pre prevedenie cesty k súboru z inštancie triedy File
na
inštanciu triedy Path
, zavoláme metódu toPath()
na
inštanciu triedy File
:
val file = File(System.getProperty("user.home") + File.separator + "itnetwork" + File.separator + "soubor.txt") val path = file.toPath()
Teraz už teda vieme ako správne vytvoriť inštancie tried
Path
a File
na použitie na akomkoľvek operačnom
systéme.
V budúcej lekcii , Práca s CSV súbormi v Kotlin - Uloženie objektov , vytvoríme formulárovú aplikáciu s databázou používateľov a naučíme sa ukladať inštancie používateľov do textových súborov vo formáte CSV.