Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
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 3 - Práce s textovými soubory v Javě

V minulém dílu seriálu tutoriálů pro Javu, Úvod do práce se soubory v Javě, jsme si ukázali, jak fungují přístupová práva v operačních systémech a jak se vytvářejí instance tříd Path a File.

V dnešním Java tutoriálu si vysvětlíme práci s textovými soubory pomocí staršího API java.io a novějšího API java.nio.

Nejjednodušší cestou, jak uložit data aplikace na pevný disk, je využít textové soubory. Se soubory s příponou .txt jsme se jistě všichni již setkali. Text je v nich uložen jednoduše na jednotlivých řádcích. K oddělení řádků se využívá speciálních znaků, které jsou bohužel specifické pro každý operační systém. Toto však za nás naštěstí vyřeší Java.

API java.io

Pojďme se nejprve podívat na starší způsob práce se soubory pomocí API java.io.

Zápis do nového textového souboru

Vytvoříme si nový projekt s názvem TextoveSoubory a v něm třídu Main s obvyklou metodou main(). K zápisu do textového souboru slouží třída FileWriter, která se ale obvykle obaluje do třídy BufferedWriter. Objekt BufferedWriter používá k zápisu na disk vyrovnávací paměť a je tudíž výrazně výkonnější. Také poskytuje metodu newLine(). Tato metoda vloží do souboru správný znak konce řádku, nezávisle na operačním systému.

Nejprve si ale vytvoříme instanci třídy File, tak jak jsme si to ukázali v této lekci. Soubor pojmenujeme třeba oldapi.txt.

File file = new File(System.getProperty("user.home") + File.separator + "itnetwork" + File.separator + "oldapi.txt");
file.getParentFile().mkdirs();

Nyní vytvoříme blok try-with-resources a v něm novou instanci typu BufferedWriter. Jak již víme z předchozích dílů, blok try-with-resources se nám automaticky postará o zavření souboru po dokončení zápisu/čtení. Do konstruktoru vložíme instanci objektu FileWriter. Samotný objekt FileWriter potřebuje objekt typu File, který jsme vytvořili výše.

try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
} catch (Exception e) {
    System.out.println("Do souboru se nepovedlo zapsat.");
}

Náš objekt BufferedWriter je nyní nasměrovaný na správný soubor. Nový řádek zapíšeme pomocí metody write(). Odřádkování v souboru docílíme metodou newLine(). Po dokončení zápisu musíme zavolat metodu flush(), která se stará o vyprázdnění bufferu. S tím se zde nebudeme zatěžovat, postačí nám vědět, že námi zapsané řádky mohou zůstat chvíli ve vyrovnávací paměti a my pomocí flush() vynutíme jejich zápis.

Kód se nám tedy rozrostl a vypadá takto:

File file = new File(System.getProperty("user.home") + File.separator + "itnetwork" + File.separator + "oldapi.txt");
file.getParentFile().mkdirs();
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
    bw.write("První řádek");
    bw.newLine();
    bw.write("Tento text je na druhém řádku");
    bw.newLine();
    bw.write("A do třetice.");
    bw.newLine();
    bw.flush();
} catch (Exception e) {
    System.out.println("Do souboru se nepovedlo zapsat.");
}

Po spuštění se vytvoří soubor oldapi.txt v našem domovském adresáři v podadresáři itnetwork. Můžeme se tam podívat a běžným textovým editorem se přesvědčit, že opravdu obsahuje náš text:

Zápis textových souborů v Javě - Soubory v Javě

Připsání textu do existujícího souboru

Takto do existujícího souboru připíšeme nový řádek:

try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true))) {
    bw.write("Připsaný řádek");
    bw.newLine();
    bw.flush();
} catch (Exception e) {
    System.out.println("Do souboru se nepovedlo zapsat.");
}

Druhým parametrem konstruktoru objektu FileWriter s hodnotou true, specifikujeme připsání do existujícího souboru, jehož původní obsah zůstane nezměněn.

Čtení existujícího souboru

Zbývá nám již jen umět soubor načíst. Není to o nic složitější, než zápis a opět k tomu máme v Javě připravenou třídu, konkrétně BufferedReader. Použití je obdobné, namísto metody write() použijeme metodu readLine(), která vrací řádek textu ze souboru a zároveň se přesune na řádek následující. Budeme ji tedy volat v cyklu while. Podmínka pro ošetření vyjetí ze souboru je možná krkolomnější, kontrolujeme, zda proběhlo přiřazení nové řádky do proměnné.

Kód k výpisu obsahu souboru do konzole vypadá 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("Chyba při čtení ze souboru.");
}

Kód celého našeho programu vypadá takto:

// zápis do souboru
File file = new File(System.getProperty("user.home") + File.separator + "itnetwork" + File.separator + "oldapi.txt");
file.getParentFile().mkdirs();
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file))) {
    bw.write("První řádek");
    bw.newLine();
    bw.write("Tento text je na druhém řádku");
    bw.newLine();
    bw.write("A do třetice.");
    bw.newLine();
    bw.flush();
    System.out.println("Do souboru bylo zapsáno");
} catch (Exception e) {
    System.out.println("Do souboru se nepovedlo zapsat.");
}

// připsání textu do existujícího souboru
try (BufferedWriter bw = new BufferedWriter(new FileWriter(file, true))) {
    bw.write("Připsaný řádek");
    bw.newLine();
    bw.flush();
    System.out.println("Do souboru bylo připsáno");
} catch (Exception e) {
    System.out.println("Do souboru se nepovedlo zapsat.");
}

// výpis obsahu souboru
System.out.println("Vypisuji celý soubor:");
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("Chyba při čtení ze souboru.");
}

A výsledek:

Zápis a čtení textových souborů v Javě - Soubory v Javě

API java.nio

Teď se podíváme na novější způsob práce se soubory pomocí API java.nio.

Zápis do nového textového souboru

Nejprve si vytvoříme instanci třídy Path. Soubor pojmenujeme třeba newapi.txt:

Path path = Path.of(System.getProperty("user.home"), "itnetwork", "newapi.txt");

K zápisu do souboru použijeme statickou metodu writeString() ze třídy Files. Nezapomeneme nejprve vytvořit všechny potřebné adresáře a zachytávat případnou výjimku. Jako oddělovač řádku použijeme univerzální oddělovač pomocí metody lineSeparator().

Metoda writeString() přijímá dva a více parametrů. První parametr je typu Path, čili soubor, do kterého chceme zapisovat. Druhý parametr je typu String, čili text, který chceme zapisovat. Poté následují nepovinné parametry typu StandardOpenOption, kterými metodě říkáme, jakým způsobem se má soubor otevřít.

Způsoby otevření souboru

Nejpoužívanější volby výčtového typu StandardOpenOption pro způsoby otevření souboru jsou tyto:

  • CREATE - vytvoří nový soubor, nevyhazuje chybu, pokud už existuje
  • CREATE_NEW - vytvoří nový soubor, vyhodí chybu, pokud soubor už existuje
  • TRUNCATE_EXISTING - při otevření vymaže obsah souboru
  • APPEND - otevře soubor pro přidávání obsahu

V následujícím příkladu při zápisu prvního řádku použijeme volbu CREATE a TRUNCATE_EXISTING, aby se soubor vytvořil a existující soubor napřed vymazal. Každý další zápis už děláme pomocí volby APPEND, aby se zapisovaný text typu String přidal na konec souboru:

try {
    Files.createDirectories(path.getParent());
    Files.writeString(path, "První řádek" + System.lineSeparator(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
    Files.writeString(path, "Tento text je na druhém řádku" + System.lineSeparator(), StandardOpenOption.APPEND);
    Files.writeString(path, "A do třetice" + System.lineSeparator(), StandardOpenOption.APPEND);
} catch (IOException ex) {
    System.out.println("Chyba při zápisu do souboru: " + ex.getMessage());
}

Stejně jako v případě staršího API java.io, se nám i nyní po spuštění programu vytvoří nový soubor s názvem newapi.txt obsahující tři řádky textu. Můžeme si to ověřit libovolným textovým editorem.

Připsání textu do existujícího souboru

Připsání řádků do již existujícího souboru děláme pomocí volby APPEND:

try {
    Files.writeString(path, "Tento text je na posledním řádku" + System.lineSeparator(), StandardOpenOption.APPEND);
} catch (IOException ex) {
    System.out.println("Chyba při zápisu do souboru: " + ex.getMessage());
}

Čtení existujícího souboru

Ke čtení řádků z textového souboru použijeme metodu readAllLines() opět ze třídy Files. Tato metoda vrací kolekci List<String>:

try {
    List<String> lines = Files.readAllLines(path);
    lines.forEach(System.out::println);
} catch (IOException ex) {
    System.out.println("Chyba při čtení souboru: " + ex.getMessage());
}

V následujícím kvízu, Kvíz - Základy práce se soubory a výjimky v Javě, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 863x (3.35 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

Předchozí článek
Úvod do práce se soubory v Javě
Všechny články v sekci
Soubory v Javě
Přeskočit článek
(nedoporučujeme)
Kvíz - Základy práce se soubory a výjimky v Javě
Článek pro vás napsal David Hartinger
Avatar
Uživatelské hodnocení:
54 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity