Hoofdstuk 5: Bestanden
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.
Bestand Bevat data (gegevens) Heeft een naam Een brief, een lijst van namen, een prijslijst van onderdelen, …. Heeft een naam Naamgeving kan onderworpen zijn aan regels Afhankelijk van het computer systeem
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”)
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
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);
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 Bestand op disk data Deze streams zijn objecten van de klasse FileOutputStream
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.
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”);
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
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!
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 ; 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.”); } } Voor het geval er iets verkeerd gaat. Bv. een bestand maken als je dat niet mag
Lezen van een bestand (1) Om van een bestand te kunnen lezen is er ook een stream nodig Java Programma Bestand op disk data Nu een FileInputStream nodig: object van de klasse FileInputStream Constructor new FileInputStream(fileObject) File f = new File(“gegevens”); FileInputStream fs = new FileInputStream(f) ;
Lezen van een bestand (2) We willen nu de input stream zien als een opeenvolging van karakters Object van de klasse InputStreamReader Java Programma Bestand op disk karacters h a l o File f = new File(“gegevens”); FileInputStream fs = new FileInputStream(f) ; InputStreamReader isr = new InputStreamReader(fs);
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() ;
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.
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() ;
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!
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”
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.flush();
Voorbeeld Maak een kopie van een bestand dat bestaat uit 2 lijnen. Voer de naam van het bestand in via het toetsenbord.
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”);
// 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);
// lees lijn van origineel bestand en schrijf weg op kopie-bestand. // doe dit 2 keer String line; line = brOrig.readLine(); psCopy.println(line); }
Voorbeeld 2 Ontwerp klasse die het afhandelen van Interactive input en output eenvoudiger maakt: class InteractiveIO
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
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)
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); }
InteractiveIO vb - Klasse skelet class InteractiveIO { instantie variabelen indien nodig public InteractiveIO() { statements } // schrijf s naar het scherm public void write(String s) { // schrijf s naar het scherm; // lees een string van het toetsenbord en geef deze als return-waarde terug public String promptAndRead(String s) {
InteractiveIO vb - Implementatie Methode write public void write(String s) { System.out.print(s) ; System.out.flush() ; //voor het direct zichtbaar zijn van s }
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 ; }
InteractiveIO vb - Implementatie (3) De constructor InteractiveIO() public InteractiveIO() { } Instantie variabelen ? Geen nodig
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
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; String line ; line = br.readLine(); return line ; } public InteractiveIO() { ? br = new BufferedReader( new InputStreamReader (System.in)); br = new BufferedReader( new InputStreamReader (System.in)); BufferReader br wordt instantie variabele
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 line ; } public InteractiveIO() throw IOException { br = new BufferedReader( new InputStreamReader (System.in)); return br.readLine();
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(); public void write(String s) { System.out.flush() ; //voor het direct zichtbaar zijn van s Methode van maken private void writeAndFlush(String s) { System.out.print(s) ; System.out.flush() ; }
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(); public void write(String s) { private void writeAndFlush(String s) { System.out.print(s) ; System.out.flush() ; //voor het direct zichtbaar zijn van s this referentie naar het object zelf
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) { 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
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 goed fout
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() ;
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
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() ;