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 
Scannerz 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 
Scannera 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.nioa 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