Hoofdstuk 5: Bestanden Inleiding Informatica Prof. Dr. O. De Troyer Bestanden op de harde schijf • Gegevens in bestanden op de harde schijf (“disk files”) zijn persistent. – Blijft bestaan ook als we de computer uitzetten • Disk files kunnen grote hoeveelheden informatie bevatten. Inleiding Informatica Prof. Dr. O. De Troyer 2001 2 Bestand • Bevat data (gegevens) – Een brief, een lijst van namen, een prijslijst van onderdelen, …. • Heeft een naam – Naamgeving kan onderworpen zijn aan regels – Afhankelijk van het computer systeem Inleiding Informatica Prof. Dr. O. De Troyer 2001 3 Operaties op bestanden • Een bestand aanmaken • Gegevens “wegschrijven” op een bestand • Een bestand verwijderen (samen met de inhoud) • Een bestand hernoemen • De inhoud van een bestand overschrijven • De inhoud van een bestand opvragen (“lezen”) Inleiding Informatica Prof. Dr. O. De Troyer 2001 4 De klasse File • Instantie (object) van de klasse File laat toe om naar een bestand te refereren. • Constructor new File(bestandsnaam) File f1, f2 ; f1 = new File(“brief”); f2 = new File(“onzin”); Opgelet! New File maakt geen nieuw bestand aan, enkel een nieuw object. Bestand hoeft niet te bestaan Inleiding Informatica Prof. Dr. O. De Troyer 2001 5 De klasse File (2) • Bestand verwijderen – Methode delete() File f ; f = new File(“onzin”); f.delete(); • Bestand hernoemen – Methode renameTo(fileObject) File f1, f2 ; f1 = new File(“onzin”); f2 = new File(“rommel”); f1.renameTo(f2); Inleiding Informatica Prof. Dr. O. De Troyer 2001 6 Schrijven op een bestand (1) • Om op een bestand te kunnen schrijven is een “stream” (soort kanaal) nodig – Een opeenvolging van data eenheden Stream Java Programma data Bestand op disk • Deze streams zijn objecten van de klasse FileOutputStream Inleiding Informatica Prof. Dr. O. De Troyer 2001 7 De klasse FileOutputStream • Constructor new FileOutputStream(fileObject) File f = new File(“vrienden”); FileOutputStream fs = new FileOutputStream(f) ; – Deze constructor opent het bestand vrienden om er op te schrijven (of overschrijven) – Indien het bestand niet bestaat wordt een bestand gemaakt. Inleiding Informatica Prof. Dr. O. De Troyer 2001 8 Schrijven op een bestand (2) • FileOutputStream object alleen is nog niet voldoende. We willen een opeenvolging van karakters kunnen schrijven: – Object van de klasse PrintStream • Constructor new PrintStream(fileOutputStreamObject) File f = new File(“gegevens.out”); FileOutputStream fs = new FileOutputStream(f) ; PrintStream pf = new PrintStream(fs) ; • Methoden: print en println pf.println(“hallo bestand”); Inleiding Informatica Prof. Dr. O. De Troyer 2001 9 Schrijven op een bestand (3) Overzicht – Maak File object om naar het bestand te refereren – Maak FileOutputStream object om het kanaal naar het bestand te representeren – Maak PrintStream object om kanaal te zien als opeenvolging van karakters. – Gebruik de print en println methoden om gegevens weg te schrijven Inleiding Informatica Prof. Dr. O. De Troyer 2001 10 File f = new File(“gegevens.out”); FileOutputStream fs = new FileOutputStream(f) ; PrintStream pf = new PrintStream(fs) ; Of PrintStream pf = new PrintStream( new FileOutputStream( new File(“gegevens.out”) ) ) ; pf.print en pf.println vervangt de eventuele inhoud van het bestand door nieuwe inhoud! Inleiding Informatica Prof. Dr. O. De Troyer 2001 11 Voorbeeld • Schrijf zowel op het scherm als op een file import java.io.*; class Programma1 { public static void main(String[] arg) throws IOException { File backupFile; FileOutputStream backupFileStream ; PrintStream backup ; Voor het geval er iets verkeerd gaat. Bv. een bestand maken als je dat niet mag backupFile = new File(“backup”); backupFileStream = new FileOutputStream(backupFile); backup = new PrintStream(backupFileStream); System.out.println(“Dit is mijn eerste Java programma”); backup. println(“Dit is mijn eerste Java programma”); System.out.println(“maar niet mijn laatste.”); backup.println(“maar niet mijn laatste.”); } } Inleiding Informatica Prof. Dr. O. De Troyer 2001 12 Lezen van een bestand (1) • Om van een bestand te kunnen lezen is er ook een stream nodig Java Programma data Bestand op disk • Nu een FileInputStream nodig: – object van de klasse FileInputStream Constructor new FileInputStream(fileObject) File f = new File(“gegevens”); FileInputStream fs = new FileInputStream(f) ; Inleiding Informatica Prof. Dr. O. De Troyer 2001 13 Lezen van een bestand (2) • We willen nu de input stream zien als een opeenvolging van karakters – Object van de klasse InputStreamReader Java Programma ha l l o karacters Bestand op disk File f = new File(“gegevens”); FileInputStream fs = new FileInputStream(f) ; InputStreamReader isr = new InputStreamReader(fs); Inleiding Informatica Prof. Dr. O. De Troyer 2001 14 Lezen van een bestand (3) • Echter objecten van de klasse InputStreamReader erkennen het einde van een lijn niet. • BufferedReader objecten kunnen dit wel File f = new File(“gegevens”); FileInputStream fs = new FileInputStream(f) ; InputStreamReader isr = new InputStreamReader(fs); BufferedReader br = new BufferedReader(isr); – Methode readLine om een lijn te lezen String s ; s = br.readLine() ; Inleiding Informatica Prof. Dr. O. De Troyer 2001 15 Lezen van een bestand (4) Overzicht – Maak File object om naar het bestand te refereren – Maak FileInputStream object om het kanaal naar het bestand te representeren – Maak InputStreamReader object om kanaal te zien als opeenvolging van karakters. – Maak BufferedReader object om opeenvolging van karakters te zien als opeenvolging van lijnen. – Gebruik de readLine methode om een lijn te lezen. Inleiding Informatica Prof. Dr. O. De Troyer 2001 16 Invoer via het toetsenbord (1) • Zoals het lezen van een bestand maar – i.p.v. een FileInputStream object gebruiken we – een BufferedInputStream object • Voor het toetsenbord is dit een voorgedefinieerd object: System.in /* File f = new File(“gegevens”); nu geen file maar invoer via toetsenbord FileInputStream fs = new FileInputStream(f) ; niet nodig System.in is voorgedefinieerd */ InputStreamReader isr = new InputStreamReader(System.in); BufferedReader keyb = new BufferedReader(isr); String s = keyb.readLine() ; Inleiding Informatica Prof. Dr. O. De Troyer 2001 17 Belangrijke opmerking • System.out is een PrintStream object – Kan direct gebruikt worden om strings op het scherm te schrijven • System.in in een BufferedInputStream object – Kan niet direct gebruikt worden om strings te lezen • BufferedReader object nog nodig! Inleiding Informatica Prof. Dr. O. De Troyer 2001 18 Interactieve programma’s • Programma’s die hun invoer (o.a.) via het toetsenbord krijgen en hun resultaten (o.a.) op het scherm zetten. • Hoe weet de eind-gebruiker wanneer hij welke invoer moet intypen? – Prompts Vb: ”Voer nu je voornaam in” Inleiding Informatica Prof. Dr. O. De Troyer 2001 19 Interactieve programma’s (2) • Voorbeeld prompt System.out.println(“Voer nu je voornaam in”); naam = keyb.readLine() ; • Echter! – Een PrintStream object verzamelt alle af te drukken strings in een buffer. – Strings worden pas afgedrukt als de buffer vol is of programma stopt. • Prompt kan nog in de buffer zitten als readLine reeds uitgevoerd wordt! – Oplossing: methode flush() maakt de buffer leeg. System.out.println(“Voer nu je voornaam in”); System.out.flush(); naam = keyb.readLine() ; Inleiding Informatica Prof. Dr. O. De Troyer 2001 20 Voorbeeld • Maak een kopie van een bestand dat bestaat uit 2 lijnen. Voer de naam van het bestand in via het toetsenbord. Inleiding Informatica Prof. Dr. O. De Troyer 2001 21 import java.io.*; class CopyFile { public static void main(String[] arg) throws IOException { // voor invoer via toetstenbord InputStreamReader isrKeyboard; BufferedReader keyboard; isrKeyboard = new InputStreamReader(System.in); keyboard = new BufferedReader(isrKeyboard); // lees naam van bestand System.out.print(“geef naam van het te kopiëren bestand: “); System.out.flush(); String fnameOrig ; fnameOrig = keyboard.readLine(); // naam van kopie-bestand String fnameCopy ; fnameCopy = fnameOrig.concat(“.copy”); Inleiding Informatica Prof. Dr. O. De Troyer 2001 22 // voor het lezen van het bestand File fOrig; FileInputStream fsOrig; InputStreamReader isrOrig; BufferedReader brOrig; fOrig = new File(fnameOrig); fsOrig = new FileInputStream(fOrig) ; isrOrig = new InputStreamReader(fsOrig); brOrig = new BufferedReader(isrOrig) ; // voor het wegschrijven op het bestand File fCopy; FileOutputStream fsCopy; PrintStream psCopy; fCopy = new File(fnameCopy); fsCopy = new FileOutputStream(fCopy) ; psCopy = new PrintStream(fsCopy); Inleiding Informatica Prof. Dr. O. De Troyer 2001 23 // lees lijn van origineel bestand en schrijf weg op kopie-bestand. // doe dit 2 keer String line; line = brOrig.readLine(); psCopy.println(line); line = brOrig.readLine(); psCopy.println(line); } } Inleiding Informatica Prof. Dr. O. De Troyer 2001 24 Voorbeeld 2 • Ontwerp klasse die het afhandelen van Interactive input en output eenvoudiger maakt: class InteractiveIO Inleiding Informatica Prof. Dr. O. De Troyer 2001 25 InteractiveIO vb - Bepaal het gedrag • We willen het volgende gedrag – Schrijf een boodschap op het scherm (moet dadelijk zichtbaar zijn) – Vraag invoer via het toetsenbord via een prompt en lees de invoer (als string) – Nieuwe objecten maken zonder te moeten refereren naar System.in of System.out Inleiding Informatica Prof. Dr. O. De Troyer 2001 26 InteractiveIO vb - Bepaal de interface – Class name: InteractiveIO – Constructor: InteractiveIO() • Vb: InteractiveIO interIO = new InteractiveIO(); public InteractiveIO() – Boodschap op het scherm schrijven: Vb: interIO.write(“Goed geantwoord!”); public void write( String s) – Invoer lezen via prompt: Vb: string s ; s = interIO.promptAndRead(“Geef je voornaam: ”); public String promptAndRead( String s) Inleiding Informatica Prof. Dr. O. De Troyer 2001 27 InteractiveIO vb - Een vb-programma Vraag invoer via de prompt “Please type a word:” en schrijf vervolgens deze invoer terug op het scherm import java.io.*; class TryInteractiveIO { public static void main(String[] arg) throws IOException { InteractiveIO interIO ; String line ; interIO = new InteractiveIO(); line = interIO.promptAndRead(“Please type a word: “); interIO.write(line); } } Inleiding Informatica Prof. Dr. O. De Troyer 2001 28 InteractiveIO vb - Klasse skelet class InteractiveIO { instantie variabelen indien nodig public InteractiveIO() { statements } // schrijf s naar het scherm public void write(String s) { statements } // schrijf s naar het scherm; // lees een string van het toetsenbord en geef deze als return-waarde terug public String promptAndRead(String s) { statements } } Inleiding Informatica Prof. Dr. O. De Troyer 2001 29 InteractiveIO vb - Implementatie • Methode write public void write(String s) { System.out.print(s) ; System.out.flush() ; } Inleiding Informatica Prof. Dr. O. De Troyer //voor het direct zichtbaar zijn van s 2001 30 InteractiveIO vb - Implementatie (2) • De methode promptAndRead public String promptAndRead(String s) throws IOException { System.out.print(s) ; System.out.flush() ; //voor het direct zichtbaar zijn van s BufferedReader br; br = new BufferedReader( new InputStreamReader (System.in)); String line ; line = br.readLine(); return line ; } Inleiding Informatica Prof. Dr. O. De Troyer 2001 31 InteractiveIO vb - Implementatie (3) • De constructor InteractiveIO() public InteractiveIO() { } • Instantie variabelen ? – Geen nodig Inleiding Informatica Prof. Dr. O. De Troyer 2001 32 InteractiveIO vb - Verbeterde Implementatie public String promptAndRead(String s) { System.out.print(s) ; System.out.flush() ; //voor het direct zichtbaar zijn van s BufferedReader br; br = new BufferedReader( new InputStreamReader (System.in)); String line ; line = br.readLine(); return line ; Telkens een nieuwe BufferReader } en InputStreamReader! Beter: • één keer nieuwe BufferReader en InputStreamReader maken – bij de constructor Inleiding Informatica Prof. Dr. O. De Troyer 2001 33 InteractiveIO vb - Verbeterde Implementatie (2) ? public String promptAndRead(String s) { System.out.print(s) ; System.out.flush() ; //voor het direct zichtbaar zijn van s BufferedReader br; br = new BufferedReader( new InputStreamReader (System.in)); String line ; line = br.readLine(); return line ; } public InteractiveIO() { br = new BufferedReader( new InputStreamReader (System.in)); } BufferReader br wordt instantie variabele Inleiding Informatica Prof. Dr. O. De Troyer 2001 34 InteractiveIO vb - Verbeterde Implementatie (3) private BufferedReader br ; public String promptAndRead(String s) throw IOException { System.out.print(s) ; System.out.flush() ; //voor het direct zichtbaar zijn van s String line ; line = br.readLine(); return br.readLine(); return line ; } public InteractiveIO() throw IOException { br = new BufferedReader( new InputStreamReader (System.in)); } Inleiding Informatica Prof. Dr. O. De Troyer 2001 35 InteractiveIO vb - Verbeterde Implementatie (4) private BufferedReader br ; public InteractiveIO() throw IOException { br = new BufferedReader( new InputStreamReader (System.in)); } public String promptAndRead(String s) throw IOException { System.out.print(s) ; System.out.flush() ; //voor het direct zichtbaar zijn van s return br.readLine(); Methode van maken } private void writeAndFlush(String s) { public void write(String s) { System.out.print(s) ; System.out.print(s) ; System.out.flush() ; System.out.flush() ; //voor } het direct zichtbaar zijn van s } Inleiding Informatica Prof. Dr. O. De Troyer 2001 36 InteractiveIO vb - Verbeterde Implementatie (5) private BufferedReader br ; public InteractiveIO() throw IOException { br = new BufferedReader( new InputStreamReader (System.in)); } public String promptAndRead(String s) throw IOException { this.writeAndFlush(s); return br.readLine(); } this referentie naar het object zelf public void write(String s) { this.writeAndFlush(s); } private void writeAndFlush(String s) { System.out.print(s) ; System.out.flush() ; //voor het direct zichtbaar zijn van s } Inleiding Informatica Prof. Dr. O. De Troyer 2001 37 InteractiveIO vb - Verbeterde Implementatie (6) private BufferedReader br ; public InteractiveIO() throw IOException { br = new BufferedReader( new InputStreamReader (System.in)); } public String promptAndRead(String s) throw IOException { this.writeAndFlush(s); return br.readLine(); } public void write(String s) { this.writeAndFlush(s); } private void writeAndFlush(String s) { System.out.print(s) ; System.out.flush() ;//voor het direct zichtbaar zijn van s } • Is writeAndFlush echt nodig ? • Voeg een methode writeln(String s) toe Inleiding Informatica Prof. Dr. O. De Troyer 2001 38 int getallen lezen Lees als String object String s = br.readLine() ; Zet de String om naar een integer door methode uit envelope klasse Integer int i = Integer.parseInt(s) ; Note: string moet een geheel getal voorstellen anders krijgen we een fout 2 -77 Hello 57 88 Inleiding Informatica goed fout Prof. Dr. O. De Troyer 2001 39 Lezen van float en double getallen • Geen parseDouble en parseFloat methoden! Lees als String object String s = br.readLine() ; Zet de String om naar een Float of Double object door methode valueOf uit enveloppe klasse Float object = Float.valueOf(s) ; Zet de Float of Double object om naar float of double door methode floatValue/doubleValue uit enveloppe klasse float f = object.floatValue() ; Inleiding Informatica Prof. Dr. O. De Troyer 2001 40 Lezen van een WWW-bestand • Zoals het lezen van een bestand maar – i.p.v. een FileInputStream object gebruiken we – een FilterInputStream object • WWW-bestanden worden geïdentificeerd door een URL (Universal Resource Locator) protocol://internet adres/bestandsnaam Vb: http://www.yahoo.com/index.html • Voorgedefinieerde klasse URL Inleiding Informatica Prof. Dr. O. De Troyer 2001 41 Lezen van een WWW-bestand (2) • De klasse URL – Constructor: new URL(string) Vb: URL u = new URL(“http://www.yahoo.com/index.html”); – De methode openStream() maakt een FilterInputStream voor een URL object. Vb: FilterInputStream fis = u.openStream(); URL u = new URL(“http://www.yahoo.com/index.html”); FilterInputStream fis = u.openStream(); InputStreamReader isr = new InputStreamReader(fis); BufferedReader br = new BufferedReader(isr); String s = br.readLine() ; Inleiding Informatica Prof. Dr. O. De Troyer 2001 42