Hoofdstuk 6: Bestandsinvoer en uitvoer

Inleiding

In dit hoofdstuk willen we inleiding geven over hoe we bestanden kunnen aanmaken, lezen en schrijven. Dit is zeer nuttig om gegevens van een berekening weg te schrijven of om gegevens in te laden die een berekening nodig heeft. Je kan dan vele zaken automatiseren.

De klasse File

  • Gegevens die opgeslagen zijn in een programma zijn tijdelijk. Wanneer het programma afsluit, dan zijn alle berekeningen, tussenresultaten, verwerkte gegevens verloren. Om gegevens permanent op te slaan, kunnen we gebruik maken van bestanden.
  • Elk bestand kan geplaatst worden in een map op de harde schijf. Een absolute bestandsnaam bevat de bestandsnaam met het complete pad en letter van de harde schijf. Bijvoorbeeld: C:\boeken\Welkom.java is de absolute bestandsnaam van het bestand Welkom.java op Windows besturingssystemen.
  • De klasse File is bedoeld om een abstractie aan te bieden dat bestandsoperaties ondersteund in een machine-onafhankelijke manier. De klasse bevat methodes om eigenschappen van bestanden en mappen te bepalen, om bestanden te hernoemen of te verwijderen. De klasse bevat geen methodes om de inhoud van bestanden te lezen of te schrijven.

  • Een bestand kan een absolute bestandsnaam hebben of een relatieve bestandsnaam.

    • Een absolute bestandsnaam bevat een directe verwijzing naar het bestand. bv. "c:\\boeken\\test.dat".
    • Een relatieve bestandsnaam is een relatieve verwijzing naar het bestand ten opzichte van het programma. bv. \\gegevens\\test.dat
  • Je gebruikt best geen absolute bestandsnamen, want dan maak je je programma heel specifiek bruikbaar voor enkel jouw computer. Bv. Je mag dan wel je bestand hebben in c:\\testdata\\simulatie1.dat, maar iemand anders niet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.io.File;
public class TestFileKlasse{
public static void main(String[] args){
File bestand = new File("beelden/foto.jpg");
System.out.println("Bestaat het bestand? " + bestand.exists());
System.out.println("Hoe groot is het bestand? " + bestand.length() + " bytes");
System.out.println("Kunnen we het bestand lezen? " + bestand.canRead());
System.out.println("Kunnen we het bestand schrijven? " + bestand.canWrite());
System.out.println("Is het een bestand? " + bestand.isFile());
System.out.println("Is het een map? " + bestand.isDirectory());
System.out.println("Is het absoluut? " + bestand.isAbsolute());
System.out.println("Is it hidden? " + bestand.isHidden());
System.out.println("Absolute pad is " + bestand.getAbsolutePath());
System.out.println("Laatst gewijzigd op " + file.lastModified());
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Invoer en uitvoer van bestanden

de klasse Scanner kan gebruikt worden voor het lezen van tekst uit een bestand en de klasse PrintWriter kan gebruikt worden om tekst te schrijven naar een bestand.

  • De klasse File bevat eigenschappen om een bestand of map te behandelen, maar niet om gegevens uit het bestand te lezen of naar het bestand te schrijven.
  • Om invoer of uitvoer te doen moeten we klassen gebruiken die dit hoor hun rekening kunnen nemen.

Schrijven naar een bestand met PrintWriter

  • De klasse PrintWriter kan gebruikt worden om gegevens te schrijven naar een tekstbestand. Hiervoor moet je eerst een object van de klasse PrintWriter maken:
PrintWriter uitvoer = new PrintWirter(bestandsnaam);
  • De klasse PrintWriter heeft methodes print, println en printf om dan de gegevens weg te schrijven.

  • Hieronder vind je een een voorbeeldprogramma voor het gebruik van de klasse PrintWriter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.io.File;
import java.io.PrintWriter;
public class SchrijfGegevens{
public static void main(String[] args) throws IOException{
//Maak een nieuw bestand
File bestand = new File("scores.txt");
if(bestand.exists()){
System.out.println("Bestand bestaat reeds");
System.exit(1);
}
//Maak een uitvoer object om in bestand te schrijven
PrintWriter uitvoer = new PrintWriter(bestand);
//Schrijf enkele gegevens weg
uitvoer.print("Jan Peters");
uitvoer.println(90);
uitvoer.print("Piet Janssens");
uitvoer.println(85);
//Sluit het bestand af
uitvoer.close();
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  • Lijnen 5-8 controleert indien het bestand reeds bestaat. Als dit zo is, dan wordt het programma beëindigd. Dit is belangrijk voor de volgende regel.
  • Door de constructor van PrintWriter aan te roepen, wordt het bestand geopend en wordt de inhoud (indien het bestand al bestond) verworpen.
  • Het verwerken (lezen en schrijven) van bestanden in Java kan aanleiding geven tot fouten waar Java geen controle over heeft. Je programma hangt immers af van zaken die buiten je eigen programma leven. Als er een zo'n situatie voorkomt moeten we dit kunnen opvangen, daarvoor hebben throws IOExcpetion geplaatst in de header van de main methode.
  • Wanneer het programma klaar is om in het bestand te schrijven, moet het bestand afgesloten worden. Indien dit niet gebeurt, kan het zijn dat niet alle gegevens in het bestand zijn weggeschreven. De methode close() wordt aangeroepen om een bestand af te sluiten.

Lezen van gegevens via de klasse Scanner

  • De klasse Scanner wordt gebruikt om zaken in te lezen (tekst of primitieve waarden). We gebruikten hiervoor het volgend stukje code om een invoer mogelijk te maken:
Scanner invoer = new Scanner(System.in);
  • Een gelijkaardige manier kunnen we gebruiken om invoer mogelijk te maken vanuit bestanden.
File bestand = new File(bestandsnaam);
Scanner invoer = new Scanner(bestand);
  • Hieronder vind je een voorbeeld hoe we de klasse Scanner moeten gebruiken:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;
import java.io.File;
public class LeesData{
public static void main(String[] args) throws Exception{
//Maak een bestand object
File bestand = new File("scores.txt");
//Maak een Scanner object voor het bestand
Scanner invoer = new Scanner(bestand);
//Lees gegevens van het bestand
while(invoer.hasNext()){
String voornaam = invoer.next();
String achternaam = invoer.next();
int score = invoer.nextInt();
System.out.println(voornaam + " " + achternaam " " + score);
}
invoer.close();
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  • Een object van de klasse Scanner heeft een object van de klasse Bestand nodig om de gegevens uit te lezen. Het uitvoeren van new Scanner(bestand) kan aanleiding geven tot een oncontroleerbare situatie, vandaar de er in de main methode ook throws Exception bijstaat.
  • Elke iteratie in de while-lus leest de voornaam, achternaam en de score.
  • Omdat we enkel een bestand lezen, hoeven we het bestand niet te af te sluiten via de methode close(), maar het is een goede manier van werken.

Hoe werkt de klasse Scanner?

  • Scanner heeft methodes om tekens (of een opeenvolging van tekens) te lezen en om te zetten naar een waarde of object. De methodes nextByte(), nextShort(), nextInt(), nextLong(), nextFloat(), nextDouble() en next() zijn methodes die tekens lezen, waarbij de tekens afgezonderd zijn door een delimiter.
  • Standaard is de delimiter witruimte (spaties, nieuwe regel,...).
  • Automatisch worden de gelezen tekens geconverteerd naar het juiste type.
  • De methodes next() en nextLine() in de klasse Scanner worden gebruikt om een stuk tekst (String) in te lezen. de methode next() wordt gebruikt om een stuk tekst in te lezen tot het eerstvolgende afscheidingsteken (delimiter) en nextLine() leest een stuk tekst in tot het einde van de regel.
  • Stel dat we een tekstbestand test.txt hebben waarin het volgende staat:
34 567
  • Het volgende wordt uitgevoerd
1
2
3
Scanner invoer = new Scanner(new File("test.txt"));
int intWaarde = invoer.nextInt();
String regel = invoer.nextLine();
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  • Dan zal de waarde van intWaarde gelijk zijn aan 34 en van regel gelijk aan " 567"

results matching ""

    No results matching ""