Práce se soubory v Javě Cílem kapitoly je naučit pracovat se soubory a adresáři v Javě. Na jednoduchých příkladech ukázat procházení adresáře, čtení z textového souboru a zápis do textového souboru. Klíčové pojmy: Adresář, soubor, třída File, výpis adresáře, selektivní výpis adresáře. Třída File, její vlastnosti a metody Pro práci se soubory i adresáři používáme třídu File Nachází se v balíčku java.io K souboru i adresáři přistupujeme vpodstatě stejně Třída File přímo nazajišťuje fyzické čtení nebo zápis, jen nám pomáhá s adresáři a soubory pracovat Pro zjištění aktuálního adresáře můžeme použít volání metody: String System.getProperty("user.dir") Konstruktor třídy File Pro vytvoření instance můžeme použít konstruktory: File(absolutniCesta, jmenosouboru) File(relativniCestaDoTMP/oddelovacAdresaru/jmenoSouboru) File(jmenoSouboru) Můžeme vytvořit instanci třídy File i pro soubor, který fyzicky neexistuje Oddělovače Oddělovač adresářů i cest se liší pro systémy UNIX a MS Windows Třída File má tyto statické proměnné nastavující oddělovače: char separatorchar String separator char pathseparatorchar String pathseparator Metody třídy File boolean exists()... zjistí, zda soubor nebo adresář na disku opravdu existuje boolen isfile()... zjistí, jestli je existující soubor nebo adresář souborem boolen isdirectory()... zjistí, jestli je existující soubor nebo adresář adresářem createnewfile()... vytvoří nový soubor mkdir()... vytvoří nový adresář mkdirs()... vytvoří více nových adresářů 5.4.2011 Práce se soubory v Javě 1/10
length()... zjistí délku souboru lastmodified()... vrací datum poslední modifikace v unixovém čase (před vypsáním předat konstruktoru třídy Date) renameto()... soubor i adresář můžeme přejmenovat delete()... soubor nebo prázdný adresář můžeme smazat String[] list()... vrací pole názvů souborů a podadresářů daného adr. File[] listfiles()... vrací pole typu File souborů a podadresářů Příklad 1: Výpis obsahu adresáře import java.io.*; public class Soubory { System.out.println("Aktuální adresář: "+System.getProperty("user.dir")); File adresar = new File("C://java"); if (adresar.exists()) { System.out.println("adresář " + adresar.getname() + " existuje"); File[] soubory = adresar.listfiles(); for (File s: soubory) { System.out.println("* " + s.getname()); else { System.out.println("adresář " + adresar.getname() + " neexistuje"); adresar.mkdir(); Příklad 2: Zjištění druhu souboru import java.io.*; public class Soubory { System.out.println("Aktuální adresář: "+System.getProperty("user.dir")); File adresar = new File("C://java"); if (adresar.exists()) { System.out.println("adresář " + adresar.getname() + " existuje"); File[] soubory = adresar.listfiles(); for (File s: soubory) { String popis = (s.isdirectory()?"adresář":"soubor"); System.out.println(popis+" " + s.getname()+" velikost: "+s.length()); else { System.out.println("adresář " + adresar.getname() + " neexistuje"); adresar.mkdir(); 5.4.2011 Práce se soubory v Javě 2/10
Příklad 3: Rekurzivní výpis adresáře výpis obsahu adresáře umístíme do metody, které jako parametr zadáme název adresáře public static void vypisadresare(string jmeno) { File adresar = new File(jmeno); File[] soubory = adresar.listfiles(); for (File s: soubory) { String popis = (s.isdirectory()?"adresář":"soubor"); System.out.println(popis+" " + s.getname()+" velikost: "+s.length()); pak metoda main() bude vypadat třeba takto: String adresar; Scanner vstup = new Scanner(System.in); System.out.println("Zadej jméno adresáře: "); adresar = vstup.next(); vypisadresare(adresar); pak budeme volat tuto metodu rekurzivně public static void vypisadresare(string jmeno) { File adresar = new File(jmeno); File[] soubory = adresar.listfiles(); for (File s: soubory) { if (s.isdirectory()) { System.out.println("*** "+s.getname()); String novyadresar = jmeno+"/"+s.getname(); vypisadresare(novyadresar); else { System.out.println("file: " + s.getname()+" velikost: "+s.length()); 5.4.2011 Práce se soubory v Javě 3/10
Čtení ze vstupů a zápis na výstupy Pro jakýkoliv přenos informace je nutné otevřít proud Proud = stream kanál, kterým proudí informace je otevírán programem, kterýpožaduje komunikaci po skončení komunikace je zapotřebí proud zavřít V balíčku java.io se nachází přes 50 tříd pro práci s proudy Rozlišujeme proudy podle směru toku dat: vstupní... z nich čteme výstupní... do nich zapisujeme Podle obsahu dat: textové... proudy znaků = 16 bitů binární... proudy bajtů = 8 bitů Abstraktní metody a třídy pro práci s proudy Vstupní proudy Výstupní proudy Znakově orientované proudy třída Reader třída Writer int read() int read(char[] pole) void write(int i) void write(char[] pole) void write(string retezec) Bajtově orientované proudy třída InputStream třída OutputStream int read() int read(byte[] pole) void write(int i) void write(byte[] pole) Metoda read() vrací při dosažení konce proudu -1 Všechny metody jsou přetížené Z dalších metod je důležitá metoda close() Každá z těchto abstraktních tříd má kolem 10 potomků Třídy provádějící fyzický přesun dat Zařízení Přesun znaků Přesun bajtů paměť soubor roura chararrayreader chararraywriter StringReader StringWriter FileReader FileWriter PipeReader PipeWriter ByteArrayInputStream ByteArrayOutputStream StringBufferInputStream FileInputStream FileOutputStream PipeInputStream PipeOutputStream 5.4.2011 Práce se soubory v Javě 4/10
Práce se soubory, neformátované čtení a zápis Třídy pro vstup a výstup znaků: FileReader a FileWriter bajtů: FileInputStream, FileInputStream Instanci těchto tříd vytvoříme pomocí třídy File Testujeme nejdříve, jestli soubor existuje Kdyby neexistoval, vyvolal by konstruktor výjimku FileNotFoundException POZOR NA NASTAVENÍ SKRÝT PŘÍPONU ZNÁMÝCH SOUBORŮ!!!! Příklad 4: Čtení znaků ze souboru import java.io.*; class CteniZapisZnaku { File vstupnisoubor = new File("vstup.txt"); File vystupnisoubor = new File("vystup.txt"); FileReader fr = new FileReader(vstupniSoubor); FileWriter fw = new FileWriter(vystupniSoubor); int c; while ((c=fr.read())!= -1) { System.out.println(c); fw.write(c); fr.close(); fw.close(); System.out.println("Soubor " + vstupnisoubor + "nelze otevřít"); Příklad 5: Čtení bajtů ze souboru class CteniZapisBajtu { File vstupnisoubor = new File("vstup.txt"); File vystupnisoubor = new File("vystup.txt"); FileInputStream fr = new FileInputStream(vstupniSoubor); FileOutputStream fw = new FileOutputStream(vystupniSoubor); int c; 5.4.2011 Práce se soubory v Javě 5/10
while ((c=fr.read())!= -1) { System.out.println(c); fw.write(c); fr.close(); fw.close(); System.out.println("Soubor " + vstupnisoubor + "nelze otevřít"); Metody tříd FileReader a FileWriter Třídy vlastností jsou to pomocné třídy, filtry nestarají se o fyzický přenos dat slouží pro úpravu dat načtených před zápisem pracují s proudem bajtů znaků příklady: bufferování = využití vyrovnávací paměti formátovaný výstup... PrintWriter, PrintStream konverze mezi znaky a bajty... InputStreamReader, OutputStreamWriter filtrování... FilterWriter, FilterInputStream vlastnost dodáme proudu tak, že jej použijeme jako parametr konstruktoru třídy dané vlastnosti: FileReader fr = new FileReader(cesta); BufferedReader in = new BufferedReader(fr); pak můžeme použít metody předka: read(), write() Bufferování použití vyrovnávací paměti urychlí vstup a výstup zapisuji do bufferu, pak s tím něco udělám lze použít pro proudy znaků: BufferedReader, BufferedWriter bajtů: BufferedInputStream, BufferedOutputStream čtení po řádcích výběrové čtení 5.4.2011 Práce se soubory v Javě 6/10
Příklad 6: Čtení ze souboru class CteniSouboru { Scanner vstup = new Scanner(System.in); String nazevsouboru; String celytext = ""; System.out.print("Zadej jméno souboru: "); nazevsouboru = vstup.next(); FileReader fr = new FileReader(nazevSouboru); BufferedReader in = new BufferedReader(fr); String radek; int i=0; while ((radek = in.readline())!= null) { System.out.println(++i + ". řádek: " + radek); celytext = new String(celyText + radek + "\n"); System.out.print("\n*** Výpis celého textu ***\n"+celytext); fr.close(); in.close(); System.out.println("Soubor " + nazevsouboru + "nelze otevřít"); Příklad 7: Zápis do souboru import java.io.*; import java.util.scanner; class CteniZapisSouboru { Scanner vstup = new Scanner(System.in); String nazevsouboru, vystup="zapis.txt"; String celytext = ""; System.out.print("Zadej jméno souboru: "); nazevsouboru = vstup.next(); FileReader fr = new FileReader(nazevSouboru); BufferedReader in = new BufferedReader(fr); FileWriter fw = new FileWriter(vystup); BufferedWriter out = new BufferedWriter(fw); String radekin, radekout; int i=0; 5.4.2011 Práce se soubory v Javě 7/10
while ((radekin = in.readline())!= null) { radekout = new String(++i + ". řádek: " + radekin); celytext = new String(celyText + radekin + "\n"); out.write(radekout); out.newline(); System.out.print("\n*** Výpis celého textu ***\n"+celytext); out.close(); fw.close(); fr.close(); in.close(); System.out.println("Soubor " + nazevsouboru + "nelze otevřít"); Příklad 8: GUI Editor import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; public class Editor extends JFrame { private JScrollPane sp = null; private JTextArea ta = null; private JMenuBar mb = null; private JMenu menu[] = new JMenu[2]; private JMenuItem mi[] = new JMenuItem[3]; private Container obsah; private String text; public Editor() { inicializaceeditoru(); //obsahokna(); zviditelneniokna(); public void inicializaceeditoru() { this.setsize(300, 200); this.settitle("textový editor"); this.setlocation(100,100); this.setlayout(new FlowLayout()); menu(); obsah = this.getcontentpane(); ta = new JTextArea(); obsah.add(ta); Font f = Font.decode("Monospaced"); if (f!= null) ta.setfont(f); sp = new JScrollPane(ta, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 5.4.2011 Práce se soubory v Javě 8/10
setcontentpane(sp); public void menu() { mb = new JMenuBar(); this.setjmenubar(mb); menu[0]= new JMenu("Soubor"); mb.add(menu[0]); mi[0] = new JMenuItem("Nový"); mi[1] = new JMenuItem("Otevřít"); mi[2] = new JMenuItem("Uložit"); int i; for (i=0; i<3; i++) { menu[0].add(mi[i]); mi[i].addactionlistener(new VyberMenu(i)); menu[1]= new JMenu("Nápověda"); mb.add(menu[1]); class VyberMenu implements ActionListener { int akce; public VyberMenu(int akce) { this.akce = akce; public void actionperformed(actionevent e) { String s = ""; switch(akce) { case 0: clear(); break; case 1: otevrit(); break; case 2: ulozit(); break; public void novy() { ta.settext("novy"); public void otevrit() { String nazev = "H:/java/_GUI/soubory/vstup.txt"; File in = new File(nazev); if (in.exists()) nactenisouboru(nazev); else ta.settext("soubor neexistuje"); public void ulozit() { String nazev = "H:/java/_GUI/soubory/vystup.txt"; zapisdosouboru(nazev); 5.4.2011 Práce se soubory v Javě 9/10
public void zapisdosouboru(string nazev) { String celytext = ta.gettext(); FileWriter fw = new FileWriter(nazev); BufferedWriter out = new BufferedWriter(fw); out.write(celytext); out.close(); JOptionPane.showMessageDialog(this, "Soubor nelze uložit.", "Chyba", JOptionPane.ERROR_MESSAGE); public void clear() { ta.settext(""); public void nactenisouboru(string nazev) { String celytext = ""; FileReader fr = new FileReader(nazev); BufferedReader in = new BufferedReader(fr); String radka; while ((radka = in.readline())!= null) { celytext = new String(celyText + radka + "\n"); ta.settext(celytext); fr.close(); in.close(); JOptionPane.showMessageDialog(this, "Soubor nelze otevřít.", "Chyba", JOptionPane.ERROR_MESSAGE); public void zviditelneniokna() { this.setdefaultcloseoperation(jframe.exit_on_close); this.setvisible(true); Literatura: Pavel Herout: Učebnice jazyka Java, Koop České Budějovice 2008 5.4.2011 Práce se soubory v Javě 10/10