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 ◦ ◦ ◦ ◦ ◦ ◦
5.4.2011
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ářů
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 { public static void main(String[] args) { 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 { public static void main(String[] args) { 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: public static void main(String[] args) { 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
Znakově orientované proudy
Bajtově orientované proudy
• • • •
Vstupní proudy
Výstupní 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)
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ěť
charArrayReader charArrayWriter StringReader StringWriter
ByteArrayInputStream ByteArrayOutputStream StringBufferInputStream
soubor
FileReader FileWriter
FileInputStream FileOutputStream
roura
PipeReader PipeWriter
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 { public static void main(String[] args) { File vstupniSoubor = new File("vstup.txt"); File vystupniSoubor = new File("vystup.txt"); try { 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(); } catch (IOException e) { System.out.println("Soubor " + vstupniSoubor + "nelze otevřít"); } } }
Příklad 5: Čtení bajtů ze souboru class CteniZapisBajtu { public static void main(String[] args) { File vstupniSoubor = new File("vstup.txt"); File vystupniSoubor = new File("vystup.txt"); try { 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(); } catch (IOException e) { 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: pak
FileReader fr = new FileReader(cesta); BufferedReader in = new BufferedReader(fr); 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 { public static void main(String[] args) { Scanner vstup = new Scanner(System.in); String nazevSouboru; String celyText = ""; System.out.print("Zadej jméno souboru: "); nazevSouboru = vstup.next(); try { 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(); } catch (IOException e) { System.out.println("Soubor " + nazevSouboru + "nelze otevřít"); } } }
Příklad 7: Zápis do souboru import java.io.*; import java.util.Scanner; class CteniZapisSouboru { public static void main(String[] args) { Scanner vstup = new Scanner(System.in); String nazevSouboru, vystup="zapis.txt"; String celyText = ""; System.out.print("Zadej jméno souboru: "); nazevSouboru = vstup.next(); try { 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(); } catch (IOException e) { System.out.println("Soubor " + nazevSouboru + "nelze otevřít"); } } }
Příklad 8: GUI Editor import import import import
javax.swing.*; java.awt.*; java.awt.event.*; java.io.*;
public class Editor extends JFrame { private private private private private private private
JScrollPane sp = null; JTextArea ta = null; JMenuBar mb = null; JMenu menu[] = new JMenu[2]; JMenuItem mi[] = new JMenuItem[3]; Container obsah; 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(); try { FileWriter fw = new FileWriter(nazev); BufferedWriter out = new BufferedWriter(fw); out.write(celyText); out.close(); } catch (IOException e) { JOptionPane.showMessageDialog(this, "Soubor nelze uložit.", "Chyba", JOptionPane.ERROR_MESSAGE); } } public void clear() { ta.setText(""); } public void nacteniSouboru(String nazev) { String celyText = ""; try { 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(); } catch (IOException e) { 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