Java: Textový vstup a výstup
Z MiS
(Rozdíly mezi verzemi)
(Rozšířeno, další příklady,...) |
(Použit PrintWriter místo BufferedWriteru - jednodušší výstup do textových souborů.) |
||
Řádka 140: | Řádka 140: | ||
− | == Zápis do souboru (<tt> | + | == Zápis do souboru (<tt>PrintWriter</tt>) == |
− | Třída <code> | + | Třída <code>PrintWriter</code> slouží pro zápis dat do textového výstupu. |
− | ; | + | ; Využívá efektivnější zápis pomocí vyrovnávací paměti (bufferu): |
*Ukládá zapisovaná data do paměťového bufferu. | *Ukládá zapisovaná data do paměťového bufferu. | ||
*Teprve při dosažení limitu data naráz zapíše. | *Teprve při dosažení limitu data naráz zapíše. | ||
*Je to efektivnější, než psát jednotlivé malé texty hned! | *Je to efektivnější, než psát jednotlivé malé texty hned! | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
; Otevření souboru | ; Otevření souboru | ||
− | + | String kodovani = "windows-1250"; | |
− | + | File soubor = new File("vystup.txt"); | |
− | + | PrintWriter out = new PrintWriter(soubor, kodovani); | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
; Metody | ; Metody | ||
− | * <code> | + | * <code>println(String text)</code> |
− | + | ** Přidá řádek do výstupního souboru. | |
− | ** Přidá do | + | |
* <code>flush()</code> | * <code>flush()</code> | ||
** Provede fyzický zápis stávajícího obsahu bufferu na výstup. | ** Provede fyzický zápis stávajícího obsahu bufferu na výstup. | ||
Řádka 176: | Řádka 163: | ||
** Provede i <code>flush()</code>. | ** Provede i <code>flush()</code>. | ||
− | Charset kodovani = Charset.forName(" | + | === Příklad — Zápis věty do souboru === |
+ | String kodovani = "windows-1250"; | ||
+ | File soubor = new File("vystup.txt"); | ||
+ | PrintWriter out = new PrintWriter(soubor, kodovani); | ||
+ | out.println("Hello world;"); | ||
+ | out.close(); | ||
+ | |||
+ | |||
+ | <div class="Poznamka"> | ||
+ | ; Můžete použít i novější knihovnu <code>java.nio</code> a třídu <code>BufferedWriter</code> | ||
+ | Museli byste si ale sami vyřešit textový zápis celých a desetinných čísel: | ||
+ | Charset kodovani = Charset.forName("windows-1250"); | ||
Path cesta = Paths.get("vystup.txt"); | Path cesta = Paths.get("vystup.txt"); | ||
BufferedWriter out = Files.newBufferedWriter(cesta, kodovani); | BufferedWriter out = Files.newBufferedWriter(cesta, kodovani); | ||
− | + | Související třídy: | |
− | + | * <tt>Charset</tt> | |
− | + | ** informace o kódování souboru | |
− | + | * <tt>Files</tt>, <tt>Paths</tt> | |
+ | ** práce s cestami a soubory. | ||
+ | </div> | ||
Řádka 202: | Řádka 202: | ||
System.in.available() > 0 | System.in.available() > 0 | ||
+ | ; System.err | ||
+ | * Chybový výstup. Na obrazovce se vypíše stejně jako u <code>System.out</code>, ale můžeme ho přesměrovat (viz práce se vstupy a výstupy ve 3. ročínku (Operační systémy): | ||
+ | System.err.println("Nastala chyba zápisu do souboru!"); | ||
== Související stránky == | == Související stránky == |
Verze z 23. 3. 2020, 22:40
Obsah |
Ošetření chyb, výjimky
- Při práci se souborem je třeba vždy počítat s tím, že může nastat chyba (soubor je poškozený, soubor někdo smazal,...).
- Java používá pro ošetření chybových stavů mechanismus výjimek (exception).
- Více o výjimkách si přečtete zde: Výjimky v Javě.
- Pro tuto chvíli bude stačit, když víte, že práci se soubory je vždy potřeba obklopit kódem pro řešení chyb:
try { // Začni provádět kód, ve kterém může nastat chybový stav... ... zde následuje kód, pracující se souborem... } catch (IOException ex) { // Co se má stát, pokud nastane chyba při práci se souborem... } catch (FileNotFoundException ex) { // Co se má stát, když zadaný soubor vůbec neexistuje }
- Více viz Výjimky v Javě.
Čtení ze souboru (Scanner
)
Třída Scanner
- Pro čtení dat z textových souborů slouží v Javě třída
Scanner
z balíčkujava.util
. - Slouží také pro čtení vstupu z klávesnice v konzolových aplikacích (aplikacích, které běží jen v příkazovém řádku).
- Zaveden od Javy 5 — nahrazuje BufferedReader.
- Výhodou je, že umí automaticky načíst čísla (včetně desetinných) z jejich textové podoby.
Třídu Scanner nepoužívejte v programech, které pracují s vlákny!
Otevření souboru
- Soubor otevřeme pro čtení tak, že vytvoříme novou instanci třídy
Scanner
a jako parametr konstruktoru předáme soubor, kterých chceme otevřít. - Jako druhý parametr konstruktoru můžeme předat také kódování znaků, které jsme při vytváření souborů použili. Pokud soubor vytváříte v Poznámkovém bloku Windows, použijte kódování
Windows-1250
.
- Konstruktory třídy
Scanner
-
Scanner(File vstupniSoubor, String encoding)
-
Scanner(Path vstupniSoubor, String encoding)
- ...
Kódování národních znaků:
- U všech konstruktorů můžeme druhý parametr vynechat, pak se použije kódování UTF-8.
- Označení běžných kódování, používaných pro češtinu:
-
windows-1250
... programy ve Windows (Poznámkový blok, Excel,...), -
cp852
... skripty pro příkazový řádek, -
uft-8
... programátorské nástroje, programy v Linuxu.
-
Pokud nenastavíte správné kódování českých znaků, třída Scanner se při ladění v prostředí NetBeans 8.0.2 (JDK 7u71) může chovat k souboru, jako by byl prázdný.
Pokud máte podobné problémy, zkuste:
a) nastavte správné kódování češtiny v konstruktoru Scanneru či zkonvertujte soubor na správné kódování (třeba pomocí Notepadu++ či jiného editoru, který umí nastavit kódování).
b) projekt přeložte (Clean & Build) a spusťte přímo výsledný JAR ze složky dist
v adresáři projektu. (viz Export balíčku JAR).
Metody třídy Scanner
- Získání dalšího bloku dat ze souboru
-
next()
- přečte celý řádek až po oddělovač (viz dále)
- při čtení z konzole (klávesnice) čeká na oddělovač
- bere jednotlivá slova, oddělená standardně bílým místem
-
int nextInt()
-
int nextDouble()
- vrací objektový typ Double.
- Desetinná čísla je třeba zadávat podle národního nastavení. Pro české nastavení tedy s desetinnou čárkou.
- Zjištění — je v souboru další blok dat?
-
boolean hasNext()
- je k dispozici další slovo?
-
boolean hasNextDouble()
- následuje na vstupu desetinné číslo?
- Další nastavení
-
useDelimiter(String delim)
, resp.useDelimiter(Pattern delim)
- Oddělovač položek na řádku, například:
out.useDelimiter(",");
- Jako oddělovač lze použít i regulární výraz (→ Wikipedia.org) reprezentovaný třídou
Pattern
. - Pro načítání jednoduchého CSV lze použít (pozor, není to plnohodnotné čtení CSV, ale mnohdy stačí):
- Oddělovač položek na řádku, například:
out.useDelimiter("\\s*[;,\n\r\t]\\s*")
- Ukončení práce se souborem
-
close()
- Ukončení práce se souborem – uzavření souboru.
- Vždy bychom měli zavolat po dokončení čtení.
Příklad: Načtení jednoho čísla ze souboru
import java.util.Scanner; import java.io.File; ... try { String nazev = "vstup.txt"; Scanner sc = new Scanner(new File(nazev), "windows-1250"); int cislo = sc.nextInt() sc.close(); } catch (FileNotFoundException ex) { System.err.println("Nenalezen soubor: "+nazev+"!"; } } catch (IOException ex) { System.err.println("Chyba čtení ze souboru "+nazev+": "+ex.getLocalizedMessage()); } } catch (InputMismatchException ex) { System.err.println("Nesprávný formát dat v souboru "+nazev+": "+ex.getLocalizedMessage()); } ...
Příklad: Načtení všech čísel ze souboru
import java.util.Scanner; import java.io.File; ... try { String nazev = "vstup.txt"; Scanner sc = new Scanner(new File(nazev), "windows-1250"); while (sc.hasNextInt()) { int cislo = sc.nextInt(); System.out.println(cislo); } sc.close(); } catch (FileNotFoundException ex) { System.err.println("Nenalezen soubor: "+nazev+"!"; } } catch (IOException ex) { System.err.println("Chyba čtení ze souboru "+nazev+": "+ex.getLocalizedMessage()); } } catch (InputMismatchException ex) { System.err.println("Nesprávný formát dat v souboru "+nazev+": "+ex.getLocalizedMessage()); } ...
Příklad: Načtení všech řádků textu ze souboru
Scanner sc = new Scanner(new File("myRows"), "windows-1250"); while (sc.hasNextLine()) { ... String radek = sc.nextLine(); ... } sc.close();
Příklad: Načtení jednoho čísla z klávesnice
- Použijte pouze v aplikacích pro příkazový řádek (ne v Greenfootu nebo aplikacích s grafickým uživatelským prostředím).
Scanner sc = new Scanner(System.in); int i = sc.nextInt(); vstup=input.next(); sc.close();
Zápis do souboru (PrintWriter)
Třída PrintWriter
slouží pro zápis dat do textového výstupu.
- Využívá efektivnější zápis pomocí vyrovnávací paměti (bufferu)
- Ukládá zapisovaná data do paměťového bufferu.
- Teprve při dosažení limitu data naráz zapíše.
- Je to efektivnější, než psát jednotlivé malé texty hned!
- Otevření souboru
String kodovani = "windows-1250"; File soubor = new File("vystup.txt"); PrintWriter out = new PrintWriter(soubor, kodovani);
- Metody
-
println(String text)
- Přidá řádek do výstupního souboru.
-
flush()
- Provede fyzický zápis stávajícího obsahu bufferu na výstup.
-
close()
- Zavře výstupní soubor.
- Provede i
flush()
.
Příklad — Zápis věty do souboru
String kodovani = "windows-1250"; File soubor = new File("vystup.txt"); PrintWriter out = new PrintWriter(soubor, kodovani); out.println("Hello world;"); out.close();
- Můžete použít i novější knihovnu
java.nio
a tříduBufferedWriter
Museli byste si ale sami vyřešit textový zápis celých a desetinných čísel:
Charset kodovani = Charset.forName("windows-1250"); Path cesta = Paths.get("vystup.txt"); BufferedWriter out = Files.newBufferedWriter(cesta, kodovani);
Související třídy:
- Charset
- informace o kódování souboru
- Files, Paths
- práce s cestami a soubory.
Standardní vstup a výstup
- Unixové programy a programy pro textový řádek často potřebují číst data ze standardního vstupu (běžně klávesnice) a zapisovat data na standardní výstup (běžně monitor).
- Pro základní práci mnohdy stačí přímo pracovat se standardním vstupem a výstupem přímo:
- System.out
- Běžně používáme pro výstup do konzole:
System.out.print("Ahoj!"); System.out.println("Vypíše řádek na obrazovku!");
- System.in
- Vyžaduje práci s vyjímkami (může vyhodit IOException), je tedy lepší použít třídu Scanner, pokud to lze.
- Čekání na stisk Enteru:
System.in.read();
- Test stisku libovolné klávesy:
System.in.available() > 0
- System.err
- Chybový výstup. Na obrazovce se vypíše stejně jako u
System.out
, ale můžeme ho přesměrovat (viz práce se vstupy a výstupy ve 3. ročínku (Operační systémy):
System.err.println("Nastala chyba zápisu do souboru!");
Související stránky