25.3 Schreiben in eine Datei und Lesen aus einer Datei | |
Ein Rechner verwaltet nicht nur Daten, die während der Laufzeit des Programms erzeugt werden. Die meisten Programme greifen auf ältere Datenbestände zurück oder erzeugen für einen späteren Gebrauch Daten. Ein Javaprogramm muss also Daten in eine Datei schreiben oder aus einer Datei Daten lösen können. Wieder benutzen wir die gleiche Technik: Beim Schreiben in eine Datei speist das Javaprogramm die zu sichernden Daten in ein Pipeline, die das System wieder ausliest und in eine Datei z.B. auf eine Festplatte speichert. Schauen wir uns das in einem Beispielprogramm an.: | |
Download: SchreibeInDatei. java |
|
Ausgabe | Nachdem
das Programm abgearbeitet ist, man erkennt dies daran, dass auf dem
Bildschirm die Ausgabe "Datei ist geschrieben!" erscheint, gibt es in dem
Verzeichnis, in dem das Programm gespeichert ist eine Datei mit dem Namen
Test.txt.
Öffnen wir diese Datei mit dem Standard-Editor von Windows, so sehen wir
den gespeicherten Text. |
![]() Ist das tatsächlich so, dass der Text in der Datei steht? Wir analysieren unser Programm und werden dabei versuchen diese Frage zu beantworten. Die Pipeline zwischen dem Javaprogramm und dem System ist sehr einfach gebaut. Sie verlangt dass die Daten als bytes eingespeist werden. Das Rechnersystem liest aus der Pipeline die Daten auch wieder in 1 Byte großen Blöcken und speichert diesen Code auf die Platte, wobei der Dateiname das System von dem Javaprogramm mitgeteilt bekommen muss. In
|
|
wird ein Ausgabestrom-Objekt
schreibeStrom
der Klasse FileInputStream
erzeugt. Als Parameter wird dem Konstruktor der Name der Datei als String
übergeben. Der Dateiname ist dabei vollkommen willkürlich. An Stelle von
Test.txt hätte man genauso gut
mein.bla oder
Test.jpg
wählen können. Warum wir es nicht tun, werden wir später sehen. Nachdem
die Pipeline angelegt ist, müssen wir nur noch die Daten in die Pipeline
einspeisen. Dazu benutzen wird die Methode
write(byte paket)
der Klasse FileOutputStream.
|
|
schreibeStrom.write((byte)text.charAt(i)); |
|
Es wird aus dem Text, den wir
speichern wollen ein Zeichen (char)
gelesen (text.charAt(i)),
explizit zu einem
byte
gecastet und danach in die Pipeline geschrieben. Ist der ganze in der
Pipeline, wir benutzen dazu eine Schleife, schließen wir die Pipeline mit
der close()-Methode,
das Rechnersystem übernimmt die Kontrolle liest aus der Pipeline die Daten
(im Prinzip nichts anderes als eine Reihung von Nullen und Einsen)
schreibt sie in die Datei auf der Festplatte und gibt die Kontrolle an das
Javaprogramm zurück. |
|
Klicken wir von Windows aus auf die
Datei Test.txt,
so wird die Datei vom Standard-Editor geöffnet, denn bei einer 'txt'-Endung
'geht Windows geht davon aus',
dass es sich um eine einfache Textdatei handelt. Wie geschieht es, dass
der Editor den Inhalt der Datei 'Test.txt'
auch als Text auf den Bildschirm schreibt? Nun das ist jetzt einfach: Der
Editor, der ja davon ausgeht, dass es sich bei der Datei um eine Textdatei
handelt, liest aus der Datei 1 Byte große Blöcke, interpretiert ihren
Inhalt als ASCII-Zeichen und schreibt das zum Zahlenwert gehörige Zeichen
auf den Bildschirm. Der Windows-Editor benutzt zum Auslesen der Datei
ebenfalls einen Eingabestrom. Und woher weiß der Editor wann, das Ende des
Datenstroms gekommen ist und deshalb nicht über das Ende hinaus liest? Es
gibt in der Datei tatsächlich eine Endemarkierung, die beim Schreiben der
Datei vom System hinzugefügt wurde.
Wir wollen diesen Sachverhalt
genauer untersuchen indem wir ein Javaprogramm schreiben, das eine Datei
ausliest. |
|
Download: LeseAusDatei. java |
|
Statt einer Ausgabe-Pipeline benutzen
wir eine EingabePipeline, die in einem
FileInputStream-Objekt
nämlich leseStrom
verwaltet wird. Mit der read()-Methode
werden aus der Ausgabe-Pipeline 1 Byte große Pakete gelesen. die
read()
als int-Werte
an das aufrufende Javaprogramm liefert, wo sie nach einem expliziten Cast
in der
byte-Variablen
zeichen
gespeichert werden. Zur Kontrolle werden diese Zeichen ausgegeben. Ein
weiterer expliziten Typenumwandlung castet den Inhalt von
zeichen
zu in einem
char. Schließlich wird die
ganze Zeichenkette aufgebaut und schließlich ausgegeben. |
|
68 105 101 115 101 114 32 84 101 120 116
32 119 105 114 100 32 105 110 32 101 105 110 101 114 32 68 97 116 101 105
32 103 101 115 112 101 105 99 104 101 114 116 33 -1 Dieser Text wird in einer Datei gespeichert!? |
|
Wir erkennen also, was tatsächlich in der Textdatei stand und dass erst die Interpretation einen Text daraus macht. Und noch ein weiteres zeigt die Ausgabe: Das letzte Zeichen in der Datei ist '-1' als Byte-Zeichen! Es übernimmt die Rolle von 'Der letzte macht die Tür zu'. Jetzt verstehen wir auch die Abbruchbedingung in unserer do-while-Schleife. Interpretieren wir dieses Schlusszeichen als char-Zeichen, dann wird daraus ein '?'-Zeichen. Der Windows-Editor gibt dieses Schlusszeichen nicht aus. Ein etwas modifiziertes Javaprogramm würde das gleiche leisten. | |
zu den | 25.4 Übungen |
zur Startseite | www.pohlig.de (C) MPohlig 2005 |