IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 17 - Práce se soubory a složkami v Javě

Dnes si popíšeme třídy v Javě, 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 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 k absolutní a relativní cestě. Je to čistě pro pořádek, abychom měli jasno.

Absolutní cesta

Je taková cesta, která začíná kořenovým prvkem souborového systému. V případě Windows to bude něco jako: 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 platformě závislá. 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ě cesta kudy jít v případě práce se soubory v programu.

Třída File

Třída File je v Javě již od první verze. Postupem času se ukázalo, že má nějaké "mouchy", které vyústily ve vytvoření nového API (ale o tom až v příští lekci).

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

File file = new File("soubor.txt");

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

public File(String pathname);
public File(String parent, String child);
public File(File parent, String child)
public 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ý soubor se myslí výsledný JAR 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/složka, která se nachází v nadřazené složce, například: "C://soubor.txt"

Třetí přetížení je stejně jako první, pouze 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. (Neplést s URL). Kompletní syntax pro URI je vidět níže:

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í.

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ů, které zabalíme do JARu. 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 (předem není jisté, v jakém tvaru ji dostanete, 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:

File file = new 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:

Konzolová aplikace
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 již napovídá, souborům nastavují nějaké vlastnosti. Jsou to:

  • setExecutable(boolean executable, boolean ownerOnly): boolean - nastaví, zda-li je soubor spustitelný; druhý parametr je nepovinný (existuje přetížení, kdy se tento parametr automaticky nastaví na true); pokud je druhý parametr true, tak se 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-li 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í -> nepůjde do něj zapisovat
  • setWritable(boolean writable, boolean ownerOnly): boolean - nastaví, zda-li 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, jinak false
  • canRead(): boolean - vrátí true, pokud lze ze souboru číst, jinak false
  • canWrite(): boolean vrátí true, pokud lze do souboru zapisovat, jinak false

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; vrátí true, pokud se soubor podařilo vytvořit, jinak false
  • delete(): boolean - smaže soubor; vrátí true, pokud se soubor podařilo smazat, jinak false
  • deleteOnExit(): void - smaže soubor až po ukončení programu
  • exists(): boolean - vrátí true, pokud soubor existuje, jinak false
  • 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; vrátí true, pokud se složka vytvořila, jinak false
  • mkdirs(): boolean - pokusí se vytvořit všechny složky v cestě; vrátí true, pokud se všechny složky vytvořily, jinak false
  • renameTo(File dest): boolean - přejmenuje soubor na nové jméno; lze chápat jako "přesun" souboru z jednoho místa na druhé; metoda je platformě závislá; nelze použít pro přesun souboru mezi dvěma souborovými systémy
  • toPath(): Path - vytvoří novou instanci rozhraní Path, o kterém si povíme v příští lekci

Problémy File API

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

  • valná většina metod vrací pouze true, nebo 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 Javě - Nové API, se seznámíme s novými třídami pro práci se soubory a složkami, které tyto problémy řeší.


 

Předchozí článek
Kvíz - Pokročilá práce s výjimkami v Javě
Všechny články v sekci
Soubory v Javě
Přeskočit článek
(nedoporučujeme)
Práce se soubory a složkami v Javě - Nové API
Článek pro vás napsal Petr Štechmüller
Avatar
Uživatelské hodnocení:
16 hlasů
Autor se věnuje primárně programování v Javě, ale nebojí se ani webových technologií.
Aktivity