|
Als Sprache, die nicht nur das Erstellen vorwiegend grafikorientierter Web-Applets ermöglicht, sondern auch zur Entwicklung von eigenständigen Anwendungen eingesetzt werden soll, bietet Java eine umfangreiche Bibliothek zum sequentiellen und wahlfreien Zugriff auf Dateien und zur Verwaltung von Verzeichnissen. Während der wahlfreie Zugriff ähnlich wie in anderen Sprachen gelöst ist, wurden bei der sequentiellen Ein-/Ausgabe neue Wege beschritten. Die dafür verwendeten Klassen realisieren das aus anderen Sprachen bekannte Konzept der Streams mit Hilfe objektorientierter Techniken.
Ein Stream wird dabei zunächst als abstraktes Konstrukt eingeführt, dessen Fähigkeit darin besteht, Zeichen auf ein imaginäres Ausgabegerät zu schreiben oder von diesem zu lesen. Erst konkrete Unterklassen binden die Zugriffsroutinen an echte Ein- oder Ausgabegeräte, wie beispielsweise an Dateien, Strings oder Kommunikationskanäle im Netzwerk.
Des weiteren bietet das Klassenkonzept von Java die Möglichkeit, Streams zu verketten oder zu schachteln. Die Verkettung von Streams ermöglicht es, mehrere Dateien zusammenzufassen und für den Aufrufer als einen einzigen Stream darzustellen. Das Schachteln von Streams erlaubt die Konstruktion von Filtern, die bei der Ein- oder Ausgabe bestimmte Zusatzfunktionen übernehmen, beispielsweise das Puffern von Zeichen, das Zählen von Zeilen oder die Interpretation binärer Daten.
Beide Konzepte sind mit normalen Sprachmitteln realisiert und können selbst erweitert werden. So ist es ohne weiteres möglich, eigene Filter zu schreiben, die den Ein- oder Ausgabestrom analysieren und anwendungsbezogene Funktionalitäten realisieren.
Alle Klassen zur Dateiein- und -ausgabe befinden sich im Paket java.io.
Um sie zu verwenden, sollte daher folgende Anweisung an den Anfang
eines Programms gestellt werden:
import java.io.*;
Bis zur Version 1.0 des JDK gab es nur Byte-Streams in Java. Wesentliches Merkmal eines Byte-Streams war es dabei, daß die Transporteinheit 8 Bit lange Bytes waren, wie sie in den meisten anderen Programmiersprachen verwendet werden. Während damit die Kompatibilität zu Textdateien, die mit konventionellen Programmiersprachen erstellt wurden oder von diesen gelesen werden sollten, gewährleistet war, gab es natürlich Reibungsverluste bei der Umwandlung zwischen Bytes und 16 Bit langen Unicode-Zeichen, wie sie innerhalb von Java benutzt werden. Zudem war die Abbildung zwischen Bytes und Characters eher unsystematisch gelöst und bot wenig Unterstützung für die Anpassung an unterschiedliche Zeichensätze und nationale Gegebenheiten.
All dies hat die JDK-Designer dazu bewogen, das Konzept der Streams in der Version 1.1 zu überdenken und die neue Gruppe der Character-Streams einzuführen. Die Character-Streams verwenden grundsätzlich 16 Bit lange Unicode-Zeichen und arbeiten daher viel besser mit den String- und Zeichentypen von Java zusammen. Um zu den 8-Bit-Zeichensätzen in externen Dateien kompatibel zu bleiben, wurden explizite Brückenklassen eingeführt, die Character-Streams in Byte-Streams überführen und umgekehrt. Diese bieten nun auch die Möglichkeit der Anpassung an spezielle Zeichensätze und lokale Besonderheiten.
Die Namensgebung für Byte-Streams in Java folgt dem Prinzip, eine Klasse für den lesenden Zugriff als InputStream und für den schreibenden Zugriff als OutputStream zu bezeichnen. Die Character-Streams dagegen werden als Reader bei lesenden und als Writer bei schreibenden Zugriffen bezeichnet. Wir werden uns bei der folgenden Darstellung der Streams im wesentlichen auf die Reader- und Writer-Klassen beschränken. Sie stellen das modernere Stream-Konzept dar und bügeln einige der Schwächen von Byte-Streams des JDK 1.0 aus. Wenn also zukünftig von Streams die Rede ist, sollen immer die Character-Streams des JDK 1.1 gemeint sein. Bei den an einigen Stellen trotzdem erforderlichen Zugriffen auf Byte-Streams werden wir dies explizit erwähnen. |
![]() |
|
![]() |
|
Go To Java 2, Addison Wesley, Version 1.0.2, © 1999 Guido Krüger, http://www.gkrueger.com |