14. diel - Práca so súbormi a zložkami v Jave
V minulej lekcii, Výnimky v Jave tretíkrát a techniky s nimi spojené , sme dokončili výnimky. Dnes si popíšeme
triedy v Jave, ktoré nie sú nijako závislé od typu súboru a ich použitie
je teda všeobecné. Umožňujú pracovať so súbormi a zložkami na úrovni
operačného systému, čo iste budeme v našich aplikáciách potrebovať. V
tejto lekcii si predstavíme triedu File
, jej metódy a
použitia.
Absolútna vs. relatívna cesta
Než sa pustíme do opisu triedy File
, v krátkosti si niečo
povieme k absolútnej a relatívnej ceste. Je to čisto pre poriadok, aby sme
mali jasno.
Absolútna cesta
Je taká cesta, ktorá začína koreňovým prvkom súborového systému. V
prípade Windows to bude niečo ako: C:\\
alebo D:\\
,
pre Linux to bude veľmi jednoducho /
. Absolútna cesta nepotrebuje
žiadne ďalšie informácie na určenie umiestnenia súboru. Všetko je na
jednom mieste. Problém ale je, že cesta je platforme závislá. Ako už bolo
naznačené, pre Windows a Linux sa líšia. Preto odporúčam absolútnej cesty
v ideálnom prípade nepoužívať. Prípadne iba pre súbory s nastavením
programu.
Relatívna cesta
Relatívna cesta nezačína v koreni súborového systému. Na miesto toho sa
počíta v závislosti k nejakému existujúcemu prvku (najčastejšie k
aktuálnemu programu), napr. obrazky/
. Toto je rozhodne cesta
kadiaľ ísť v prípade práce so súbormi v programe.
Trieda File
Trieda File
je v Jave už od prvej verzie. Postupom času sa
ukázalo, že má nejaké "muchy", ktoré vyústili vo vytvorenie nového API
(ale o tom až v budúcej lekcii).
Trieda reprezentuje ako súbor, tak i zložku. Pre prácu so súborom / zložkou je potreba vytvoriť novú inštanciu. To možno vykonať veľmi jednoducho:
File file = new File("soubor.txt");
Konštruktor má celkom 4 preťaženie:
public File(String pathname); public File(String parent, String child); public File(File parent, String child) public File(URI uri)
V prvom prípade možno dosadiť ako absolútna, tak relatívnu cestu. Ak použijete relatívnu cestu, výsledok sa bude vždy počítať z použitého súboru.
Použitý súbor sa myslí výsledný JAR súbor, nie * .class.
Druhé preťaženie prijíma dva reťazce. Prvý reťazec predstavuje cestu k rodičmi a môže byť ako relatívna, tak absolútna. Druhý parameter je cesta relatívna k rodičovi v prvom parametri.
Rodič je akákoľvek nadradená zložka, napríklad "C: //". Potomok je súbor / zložka, ktorá sa nachádza v nadradenej zložke, napríklad: "C: //soubor.txt"
Tretia preťaženia je rovnako ako prvý, len sa líšia v prvom parametri,
ktorým je teraz iná inštancia triedy File
.
Posledné preťaženie prijíma tzv. URI. Je to skratka pre Uniform Resource Identifier. (Nepliesť s URL). Kompletné syntax pre URI je vidieť nižšie:
URI je štandard pre identifikáciu dokumentov, využívajúci schéma popísané nižšie. URL je "podmnožina" URI a obsahuje informácie, ako spracovať zdroje z nejakého umiestnenia.
scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]
Toto je všeobecné schéma. Nám postačí iba základné, kde za časť "scheme" dosadíme 'file' a potom až cestu.
file:/tmp/soubor.txt
S týmto prístupom sa najčastejšie stretneme pri použití
rôznych obrázkov, zvukov a ďalších súborov, ktoré zabalíme do jari. K
týmto súborom zvyčajne pristupujeme pomocou metódy
getClass().getResource(String name)
. Táto metóda vracia práve
URI, ktoré odovzdáme konstruktoru triedy File
.
Najčastejšie ale budeme pracovať s prvým preťažením konstruktoru.
Metódy triedy File
Metódy si roztriedime do niekoľkých kategórií:
- get
- set
- can
- is
- funkčné
Get metódy
Máme k dispozícii nasledujúce get metódy, ktoré si všetky hneď prakticky vyskúšame:
getAbsolutePath(): String
- vráti absolútnu cestu k súborugetCanonicalPath(): String
- vráti canonizovanou cestu k súborugetFreeSpace(): long
- vráti počet voľných bytov v oddielu, v ktorom sa súbor nachádzagetName(): String
- vráti názov súborugetParent(): String
- vráti absolútnu cestu k rodičovi, alebonull
, ak súbor je sám rodičgetParentFile(): File
- vráti inštanciu triedyFile
reprezentujúci rodičia aktuálneho súborugetPath(): String
- vráti cestu k súboru (vopred nie je isté, v akom tvare ju dostanete, preto je lepšie používaťgetCanonicalPath()
getTotalSpace(): long
- vráti celkový počet bytov v oddielu, v ktorom sa súbor nachádzagetUsableSpace(): long
- vráti počet použiteľných bytov pre aktuálny virtuálny stroj; výsledok je presnejší, než z metódygetFreeSpace()
Pre istotu si napíšeme aj príklady použitia. Vytvoríme jednu inštanciu
triedy File
a zavoláme nad ňou všetky GET metódy.
Pre demonštráciu som schválne vytvoril nešikovnou zložkovú štruktúru, aby boli vidieť rozdiely medzi jednotlivými metódami. Zložky sú vytvorené nasledovne:
src |---cz | |---itnetwork | |---souboryslozky | |---App.java |---soubory | |---soubor.txt
Inštanciu triedy File
vytvoríme takto:
File file = new File("../../../soubory/soubor.txt");
Schválne sme použili niekoľkokrát sekvenciu
../
, ktorá nás vráti o zložku späť vzhľadom k aktuálnej
zložke, aby bol výsledok zaujímavejšie.
Výstup jednotlivých metód:
Konzolová aplikácia
getAbsolutePath(): /tmp/itn/soubory-slozky/../../../soubory/soubor.txt
getCanonicalPath(): /soubory/soubor.txt
getFreeSpace(): 0
getName(): soubor.txt
getParent(): ../../../soubory
getParentFile(): ../../../soubory
getPath(): ../../../soubory/soubor.txt
getTotalSpace(): 0
getUsableSpace(): 0
SET metódy
Set metódy, ako názov už napovedá, súborom nastavujú nejaké vlastnosti. Sú to:
setExecutable(boolean executable, boolean ownerOnly): boolean
- nastaví, či je súbor spustiteľný; druhý parameter je nepovinný (existuje preťaženie, kedy sa tento parameter automaticky nastaví natrue
); ak je druhý parametertrue
, tak sa aktivitu behu nastaví len aktuálnemu užívateľovisetLastModified(long time): boolean
- nastaví dátum poslednej úpravysetReadable(boolean readable, boolean ownerOnly): boolean
- nastaví, či je súbor možné čítať; pre druhý parameter platí to isté ako u prvej metódysetReadOnly(): boolean
- jednosmerná metóda, pomocou ktorej sa nastaví súbor iba pre čítanie -> nepôjde do neho zapisovaťsetWritable(boolean writable, boolean ownerOnly): boolean
- nastaví, či je možné do súboru zapisovať; pre druhý parameter platí to isté ako u prvej metódy
CAN metódy
Can metódy máme nasledujúce:
canExecute(): boolean
- vrátitrue
, ak možno súbor spustiť, inakfalse
canRead(): boolean
- vrátitrue
, ak možno zo súboru čítať, inakfalse
canWrite(): boolean
vrátitrue
, ak sa dá do súboru zapisovať, inakfalse
IS metódy
Pomocou "IS" metód sa môžeme pýtať na tieto veci:
isAbsolute(): boolean
- vrátitrue
, ak bola inštancia vytvorená za pomoci absolútnej cestyisDirectory(): boolean
- vrátitrue
, ak ide o zložkuisFile(): boolean
- vrátitrue
, ak ide o súborisHidden(): boolean
- vrátitrue
, ak je súbor skrytý
Funkčne metódy
Z preberaných metód nám už len chýba tvz. "Funkčné" metódy, teda také metódy, ktoré niečo vykonáva so samotným súborom a ktoré budeme využívať najčastejšie.
toURI(): URI
- vytvorí URI z použitej inštancie súborucreateNewFile(): boolean
- vytvorí nový súbor ak neexistuje; vrátitrue
, ak sa súbor podarilo vytvoriť, inakfalse
delete(): boolean
- zmaže súbor; vrátitrue
, ak sa súbor podarilo zmazať, inakfalse
deleteOnExit(): void
- zmaže súbor až po ukončení programuexists(): boolean
- vrátitrue
, ak súbor existuje, inakfalse
length(): long
- vráti veľkosť súboru v bytochlist(): String[]
- vráti pole absolútnych ciest súborov v priečinkulistFiles(): File[]
- vráti pole inštancií súboru v zložkemkdir(): boolean
- pokúsi sa vytvoriť priečinok; vrátitrue
, ak sa zložka vytvorila, inakfalse
mkdirs(): boolean
- pokúsi sa vytvoriť všetky zložky v ceste; vrátitrue
, ak sa všetky zložky vytvorili, inakfalse
renameTo(File dest): boolean
- premenuje súbor na nové meno; možno chápať ako "presun" súboru z jedného miesta na druhé; metóda je platforme závislá; nemožno použiť pre presun súboru medzi dvoma súborovými systémamitoPath(): Path
- vytvorí novú inštanciu rozhraniaPath
, o ktorom si povieme v budúcej lekcii
Problémy File API
File
API trpia nasledujúcimi nedostatkami:
- veľká väčšina metód vracia iba
true
, alebofalse
v prípade, že sa niečo nepodarí; problém je, že nepoznáme príčinu neúspechu - premenovanie súboru nefunguje na všetkých platformách rovnako
- API nepodporuje symbolické linky
- v API chýba podpora metadát (povolenie, vlastník súboru ...)
V budúcej lekcii, Práca so súbormi a zložkami v Jave - Nové API , sa zoznámime s novými triedami pre prácu so súbormi a zložkami, ktoré tieto problémy rieši.