NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Lekce 14 - Práce se soubory a složkami v Kotlin - Třída File

V minulé lekci, Pokročilé techniky pro práci s výjimkami v Kotlin, jsme dokončili výjimky. Ukázali jsme si jejich řetězení a další užitečné techniky

Dnes si popíšeme třídy v Kotlin, které nejsou nijak závislé na typu souboru a jejich použití je tedy obecné. Umožňují pracovat se soubory a složkami na úrovni operačního systému, což jistě budeme v našich aplikacích potřebovat. V této lekci našeho tutoriálu si představíme třídu File, její metody a použití.

Absolutní vs. relativní cesta

Než se pustíme do popisu třídy File, v krátkosti si něco řekneme o absolutní a relativní cestě. Je to čistě pro pořádek, abychom měli jasno.

Absolutní cesta

Absolutní cesta začíná kořenovým prvkem souborového systému. V případě Windows to bude C:\\ nebo D:\\, pro Linux to bude velice jednoduše /. Absolutní cesta nepotřebuje žádné další informace k určení umístění souboru. Vše je na jednom místě. Problém ale je, že cesta je závislá na platformě. Jak již bylo naznačeno, pro Windows a Linux se liší. Proto doporučuji absolutní cesty v ideálním případě nepoužívat. Případně pouze pro soubory s nastavením programu.

Relativní cesta

Relativní cesta nezačíná v kořeni souborového systému. Na místo toho se počítá v závislosti k nějakému existujícímu prvku, nejčastěji k aktuálnímu programu, např. obrazky/. Toto je rozhodně způsob, kudy jít v případě práce se soubory v programu.

Třída File

Třídu File poskytuje Java již od první verze. Můžeme ji tedy bez problému využít i pro tvorbu našich Kotlin aplikací. Postupem času se však ukázalo, že má nějaké "mouchy", které vyústily ve vytvoření nového API. To si představíme v dalších lekcích.

Třída File reprezentuje jak soubor, tak i složku. Pro práci se souborem či složkou je potřeba vytvořit novou instanci. To lze provést velmi jednoduše:

val file = File("soubor.txt")

Konstruktor má celkem 4 přetížení:

File(String pathname)
File(String parent, String child)
File(File parent, String child)
File(URI uri)

V prvním případě lze dosadit jak absolutní, tak relativní cestu. Pokud použijete relativní cestu, výsledek se bude vždy počítat z použitého souboru.

Použitým souborem se myslí výsledný .kt soubor, ne *.class.

Druhé přetížení přijímá dva řetězce. První řetězec představuje cestu k rodiči a může být jak relativní, tak absolutní. Druhý parametr je cesta relativní k rodiči v prvním parametru. Rodič je jakákoliv nadřazená složka, například C://. Potomek je soubor nebo složka, která se nachází v nadřazené složce, například C://soubor.txt.

Třetí přetížení se liší v prvním parametru, kterým je nyní jiná instance třídy File.

Poslední přetížení přijímá tzv. URI. Je to zkratka pro Uniform Resource Identifier.

URI si nebudeme plést s URL. URI je standard pro identifikaci dokumentů, využívající schéma popsané níže. URL je "podmnožina" URI a obsahuje informace, jak zpracovat zdroje z nějakého umístění.

Kompletní syntax pro URI vypadá následovně:

scheme:[//[user:password@]host[:port]][/]path[?query][#fragment]

Toto je obecné schéma. Nám postačí pouze základní, kde za část scheme dosadíme file a pak až cestu:

file:/tmp/soubor.txt

S tímto přístupem se nejčastěji setkáme při použití různých obrázků, zvuků a dalších souborů. K těmto souborům obvykle přistupujeme pomocí metody getClass().getResource(String name). Tato metoda vrací právě URI, které předáme konstruktoru třídy File.

Nejčastěji ale budeme pracovat s prvním přetížením konstruktoru.

Metody třídy File

Metody si roztřídíme do několika kategorií:

  • get,
  • set,
  • can,
  • is,
  • funkční.

GET metody

Máme k dispozici následující GET metody, které si všechny hned prakticky vyzkoušíme:

  • getAbsolutePath(): String - vrátí absolutní cestu k souboru,
  • getCanonicalPath(): String - vrátí canonizovanou cestu k souboru,
  • getFreeSpace(): long - vrátí počet volných bytů v oddílu, ve kterém se soubor nachází,
  • getName(): String - vrátí název souboru,
  • getParent(): String - vrátí absolutní cestu k rodiči, nebo null, pokud soubor je sám rodič,
  • getParentFile(): File - vrátí instanci třídy File reprezentující rodiče aktuálního souboru,
  • getPath(): String - vrátí cestu k souboru, ale předem není jisté, v jakém tvaru ji dostaneme, proto je lepší používat getCanonicalPath(),
  • getTotalSpace(): long - vrátí celkový počet bytů v oddílu, ve kterém se soubor nachází,
  • getUsableSpace(): long - vrátí počet použitelných bytů pro aktuální virtuální stroj, výsledek je přesnější, než z metody getFreeSpace().

Pro jistotu si napíšeme i příklady použití. Vytvoříme jednu instanci třídy File a zavoláme nad ní veškeré GET metody.

Pro demonstraci jsem schválně vytvořil nešikovnou složkovou strukturu, aby byly vidět rozdíly mezi jednotlivými metodami. Složky jsou vytvořeny následovně:

src
|---cz
|   |---itnetwork
|       |---souboryslozky
|           |---App.java
|---soubory
|   |---soubor.txt

Instanci třídy File vytvoříme takto:

val file = File("../../../soubory/soubor.txt")

Schválně jsme použili několikrát sekvenci ../, která nás vrátí o složku zpět vzhledem k aktuální složce, aby byl výsledek zajímavější.

Výstup jednotlivých metod:

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 metody

SET metody, jak název napovídá, souborům nastavují nějaké vlastnosti. Jsou to:

  • setExecutable(boolean executable, boolean ownerOnly): boolean - nastaví, zda je soubor spustitelný, druhý parametr uvádět nemusíme, pak má hodnotu true a spustitelnost nastaví pouze aktuálnímu uživateli,
  • setLastModified(long time): boolean - nastaví datum poslední změny souboru,
  • setReadable(boolean readable, boolean ownerOnly): boolean - nastaví, zda je soubor možné číst, pro druhý parametr platí to samé, jako u první metody,
  • setReadOnly(): boolean - jednosměrná metoda, pomocí které se nastaví soubor pouze pro čtení a nepůjde do něj zapisovat,
  • setWritable(boolean writable, boolean ownerOnly): boolean - nastaví, zda je možné do souboru zapisovat, pro druhý parametr platí to samé jako u první metody.

CAN metody

CAN metody máme následující:

  • canExecute(): boolean - vrátí true, pokud lze soubor spustit,
  • canRead(): boolean - vrátí true, pokud lze ze souboru číst,
  • canWrite(): boolean vrátí true, pokud lze do souboru zapisovat.

IS metody

Pomocí IS metod se můžeme ptát na tyto věci:

  • isAbsolute(): boolean - vrátí true, pokud byla instance vytvořena za pomoci absolutní cesty,
  • isDirectory(): boolean - vrátí true, pokud se jedná o složku,
  • isFile(): boolean - vrátí true, pokud se jedná o soubor,
  • isHidden(): boolean - vrátí true, pokud je soubor skrytý.

Funkční metody

Z probíraných metod nám už jenom chybí tvz. funkční metody, tedy takové metody, které něco provádí se samotným souborem a které budeme využívat nejčastěji:

  • toURI(): URI - vytvoří URI z použité instance souboru,
  • createNewFile(): boolean - vytvoří nový soubor pokud neexistuje a vrátí true, pokud se soubor podařilo vytvořit,
  • delete(): boolean - smaže soubor a vrátí true, pokud se jej smazat podařilo,
  • deleteOnExit(): void - smaže soubor až po ukončení programu,
  • exists(): boolean - vrátí true, pokud soubor existuje,
  • length(): long - vrátí velikost souboru v bytech,
  • list(): String[] - vrátí pole absolutních cest souborů ve složce,
  • listFiles(): File[] - vrátí pole instancí souboru ve složce,
  • mkdir(): boolean - pokusí se vytvořit složku a vrátí true, pokud se složka vytvořila,
  • mkdirs(): boolean - pokusí se vytvořit všechny složky v cestě, opět vrátí true, pokud se všechny složky vytvořily,
  • renameTo(File dest): boolean - přejmenuje soubor na nové jméno, což lze chápat jako "přesun" souboru z jednoho místa na druhé, metoda je platformě závislá a nelze použít pro přesun souboru mezi dvěma souborovými systémy,
  • toPath(): Path - vytvoří novou instanci rozhraní Path.

Problémy File API

File API trpí následujícími nedostatky:

  • Valná většina metod vrací pouze false v případě, že se něco nepovede. Problém je, že neznáme příčinu neúspěchu.
  • Přejmenování souboru nefunguje na všech platformách stejně.
  • API nepodporuje symbolické linky.
  • V API chybí podpora metadat (oprávnění, vlastník souboru...).

V příští lekci, Práce se soubory a složkami v Kotlin - Nové API, se seznámíme s novými třídami pro práci se soubory a složkami, které problémy řeší nedostatky starší třídy File.


 

Předchozí článek
Pokročilé techniky pro práci s výjimkami v Kotlin
Všechny články v sekci
Soubory a práce s nimi v Kotlin
Přeskočit článek
(nedoporučujeme)
Práce se soubory a složkami v Kotlin - Nové API
Článek pro vás napsal Filip Studený
Avatar
Uživatelské hodnocení:
1 hlasů
.
Aktivity