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 bestandWelkom.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
- Een absolute bestandsnaam bevat een directe verwijzing naar het bestand. bv.
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.
Invoer en uitvoer van bestanden
de klasse
Scanner
kan gebruikt worden voor het lezen van tekst uit een bestand en de klassePrintWriter
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 methodesprint
,println
enprintf
om dan de gegevens weg te schrijven.Hieronder vind je een een voorbeeldprogramma voor het gebruik van de klasse
PrintWriter
- 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:
- Een object van de klasse
Scanner
heeft een object van de klasseBestand
nodig om de gegevens uit te lezen. Het uitvoeren vannew Scanner(bestand)
kan aanleiding geven tot een oncontroleerbare situatie, vandaar de er in de main methode ookthrows 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()
ennext()
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()
ennextLine()
in de klasseScanner
worden gebruikt om een stuk tekst (String
) in te lezen. de methodenext()
wordt gebruikt om een stuk tekst in te lezen tot het eerstvolgende afscheidingsteken (delimiter) ennextLine()
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
- Dan zal de waarde van
intWaarde
gelijk zijn aan34
en vanregel
gelijk aan" 567"