BufferedReader načítatá textová data do paměti (buffer) a umožňuje efektivnější čtení po řádcích. Obdobně to platí pro BufferedWriter, který zase zapisuje po blocích a ne znak po znaku. Blok try-with-resources zjednodušuje práci se zdroji a zpracování výjimek a je vhodný například právě pro načítání ze a zápis do souborů. Zdroje (zde to představuje streamy pro čtení a zápis) definované v části try budou po skončení bloku (a nebo v případě vyhození výjimky) korektně uzavřeny.
V následujícím příkladu čtu ze souboru input.txt
, který je uložen v kódování Windows-1250 a hned načtené řádky ukládám do souboru output.txt
. Pro ukládání používám kódování UTF-8. Soubor input.txt se nachází v adresáři s projektem (v adresáři, kde je i složka src).
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; public class App { public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException, IOException { try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt"), "Cp1250"))) { try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8"))) { String line = null; while ((line = br.readLine()) != null) { System.out.println(line); bw.write(line); bw.newLine(); } } } } }
Pravděpodobně jste si všimli, pro někoho trochu divoké, konstrukce BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt"), "Cp1250"))
. Při práci se streamy se jednotlivé streamy zabalují do sebe a tím se výslednému streamu přidává funkcionalita. V tomto příkladu FileInputStream dokáže číst ze souboru ale pouze ve výchozím kódování. Pokud je kódování jiné, výstup vypadá třeba takto:
�lu�ou�k� k�� �p�l ��belsk� �dy.
Pokud ale tento stream zabalíme do InputStreamReader, může určit i kódování souboru. Stále ale načítáme znaky jednotlivě, což není příliš efektivní a určitě by bylo lepší je načítat po blocí (po řádcích). V tom případě použijeme BufferedReader, kterému předáme jako parametr InputStreamReader. Obdobné je i pro zapisování BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("output.txt"), "UTF-8"))
. Zde se ale zase používají streamy obsahující v názvu Writer nebo Output.
Samotné čtení a zápis se děje v této části:
String line = null; while ((line = br.readLine()) != null) { System.out.println(line); bw.write(line); bw.newLine(); }
Do proměnné line postupně načítáme řádky. V případě že BufferedReader#readLine() vrátí null znamená to, že jsem na konci souboru. Pro zápis se používá metoda BufferedWriter#write(). Pokud chceme zapsat konec rádky, používá se metoda BufferedWriter#newLine(). Po skončení práce se streamy by se na nich měla zavolat metoda close(). To platí i v případě, že máme otevřený stream a dojde k výjimce. Používám ale blok try-with-resources takže to udělá za mě.
Zdroje: