Java: Textový vstup a výstup
m (Upraveno pořadí kapitol a názvy.) |
(Přidáno ošetření chyb.) |
||
| Řádka 1: | Řádka 1: | ||
[[Category:VSE]][[Category:Informatika]][[Category:Java]] | [[Category:VSE]][[Category:Informatika]][[Category:Java]] | ||
| − | == Čtení ze souboru (< | + | == 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 (<code>Scanner</code>) == | ||
| + | |||
| + | === Třída <code>Scanner</code> == | ||
| + | * Pro čtení dat z textových souborů slouží v Javě třída <code>Scanner</code>. | ||
| + | * 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 <tt>BufferedReader</tt>. | * Zaveden od Javy 5 — nahrazuje <tt>BufferedReader</tt>. | ||
| + | * Výhodou je, že umí automaticky načíst čísla (včetně desetinných) z jejich textové podoby. | ||
<div class="Varovani">Třídu Scanner nepoužívejte v programech, které pracují s [[Vlákna v Javě|vlákny]]!</div> | <div class="Varovani">Třídu Scanner nepoužívejte v programech, které pracují s [[Vlákna v Javě|vlákny]]!</div> | ||
| − | ; Konstruktory: | + | === Otevření souboru === |
| + | * Soubor otevřeme pro čtení tak, že vytvoříme novou instanci třídy <code>Scanner</code> 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í <code>Windows-1250</code>. | ||
| + | |||
| + | ; Konstruktory třídy <code>Scanner</code>: | ||
* <code>Scanner(File vstupniSoubor, String encoding)</code> | * <code>Scanner(File vstupniSoubor, String encoding)</code> | ||
* <code>Scanner(Path vstupniSoubor, String encoding)</code> | * <code>Scanner(Path vstupniSoubor, String encoding)</code> | ||
| Řádka 29: | Řádka 52: | ||
</div> | </div> | ||
| − | + | === Metody třídy <code>Scanner</code> === | |
* <code>next()</code> | * <code>next()</code> | ||
** přečte celý řádek až po oddělovač (viz dále) | ** přečte celý řádek až po oddělovač (viz dále) | ||
| Řádka 48: | Řádka 71: | ||
out.useDelimiter("\\s*[;,\n\r\t]\\s*") | out.useDelimiter("\\s*[;,\n\r\t]\\s*") | ||
| − | + | === Příklad: Načtení čísel ze souboru === | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
Scanner sc = new Scanner(new File("myNumbers")); | Scanner sc = new Scanner(new File("myNumbers")); | ||
while (sc.hasNextLong()) { | while (sc.hasNextLong()) { | ||
| Řádka 60: | Řádka 78: | ||
... | ... | ||
} | } | ||
| + | sc.close(); | ||
| + | |||
| + | === Příklad: Načtení všech řádků textu ze souboru === | ||
Scanner sc = new Scanner(new File("myRows"), "windows-1250"); | Scanner sc = new Scanner(new File("myRows"), "windows-1250"); | ||
while (sc.hasNextLine()) { | while (sc.hasNextLine()) { | ||
| Řádka 67: | Řádka 88: | ||
... | ... | ||
} | } | ||
| + | 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(); | ||
| + | |||
| + | |||
| Řádka 111: | Řádka 142: | ||
out.newLine(); | out.newLine(); | ||
out.close(); | out.close(); | ||
| + | |||
| + | |||
| Řádka 132: | Řádka 165: | ||
== Související stránky == | == Související stránky == | ||
* [[Práce se soubory v Javě]] | * [[Práce se soubory v Javě]] | ||
| + | * [[Výjimky v Javě]] | ||
Verze z 17. 3. 2020, 15:14
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. - 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.
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
-
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.
-
boolean hasNext()- je k dispozici další slovo?
-
boolean hasNextDouble()- následuje na vstupu desetinné číslo?
-
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*")
Příklad: Načtení čísel ze souboru
Scanner sc = new Scanner(new File("myNumbers"));
while (sc.hasNextLong()) {
...
long aLong = sc.nextLong();
...
}
sc.close();
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 (BufferedWriter)
Třída BufferedWriter slouží pro zápis dat do textového výstupu.
- Princip
- 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í standardního výstupu
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
Tuto variantu používáme tehdy, kdy chceme společnou metodu pro psaní do souboru i na standardní výstup. Pro standardní výstup jinak samozřejmě stačí:
System.out.println(...);
- Otevření souboru
Charset kodovani = Charset.forName("utf-8");
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
- umí i otevřít BufferedWriter.
- Metody
-
write(String text) -
newLine()- Přidá do výstupu konec řádku. Respektuje národní nastavení a platformové závislosti.
-
flush()- Provede fyzický zápis stávajícího obsahu bufferu na výstup.
-
close()- Zavře výstupní soubor.
- Provede i
flush().
Charset kodovani = Charset.forName("utf-8");
Path cesta = Paths.get("vystup.txt");
BufferedWriter out = Files.newBufferedWriter(cesta, kodovani);
out.write("blabla");
out.newLine();
out.close();
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
Související stránky