Streams (Java)

Aus Byte-Welt Wiki
Zur Navigation springenZur Suche springen
Baustelle.png Dieser Beitrag wird derzeit noch bearbeitet. Der Text ist deshalb unvollständig und kann Fehler oder ungeprüfte Aussagen enthalten.

Einen Stream kann man, wie der Name schon sagt, mit einem Strom/Fluss vergleichen. Die Quelle fügt immer wieder neue Pakete (Wasser) nach und an einer Stelle entnimmt man diese Paktete. Wobei die Pakete solange im Stream vorhanden sind bis sie entnommen wurden.

Bei den Streams unterscheidet man zwei verschiedene Arten von Streams. Die einen sind die Streams zum Einlesen (InputStream) und die Anderen zur Ausgabe (OutputStream), welche jeweils durch ein abstrakte Klasse repräsentiert werden. Als weitere Untergruppen gibt es jeweils Streams, die für die Verarbeitung von Binärdaten und für normalen Text ausgelegt sind. Es wäre auch möglich alles über die Binärstreams zu machen, aber es ist für den Programmierer oft von Vorteil wenn er direkt mit String Objekten arbeiten kann und nicht erst alles in byte Daten umrechnen muss.

Ein Stream kann man auf jede beliebige Quelle richten, so ist es wie schon erwähnt möglich das ein Stream auf eine Datei gerichtet ist, um aus ihr Daten zu lesen oder in sie zu schreiben, genauso ist es auch möglich, dass ein Stream über ein Socket auf einen bestimmten Port lauscht und von dort Daten empfängt bzw. sendet.

Als Konstanten gibt es in der System Klasse drei Streams, welche auf die Konsole zeigen, die statische Konstante System.in ist ein InputStream, welcher zum Einlesen von der Konsole benutzt werden kann, und die beiden statischen Konstanten System.out und System.err sind ein PrintStream, welcher ein OutputStream ist.

InputStream

Durch die abstrakte Klasse InputStream aus dem Package java.io dient als Basisklasse für alle Streams um Daten einzulesen. Sie hat folgenden Methoden:

public abstract int read()

public int read(byte[] b)

public int read(byte[] b, int off, int len)

public int available()

public void close()

public void mark(int readlimit)

public boolean markSupported()

public void reset()

public long skip(long n)

Um zu erfahren, ob in dem Stream Daten vorhanden sind, kann man die Methode available() benutzen, welche true zurück gibt, wenn Daten vorhanden sind.

Mit der Methode skip(long) kann man Bytes überspringen, wobei der übergebene Wert die Anzahl angibt.

Die read()-Methoden liefern die Anzahl der gelesenen Bytes zurück, und -1 wenn das Ende der Datei erreicht ist.

Der read(byte[])-Methode wird ein byte-Array übergeben, in den die Daten aus dem Stream geschrieben werden, wobei im Normalfall die Anzahl der gelesenen Daten der Größe des Arrays entspricht. Der Aufruf der Methode entspricht dem Aufruf read(b, 0, b.length).

Die read(byte[], int, int) liest die Daten in den Array, wie die read(byte[]) Methode, zusätzlich kann man noch die einen Offset angegeben werden und die Größe die vom Stream eingelesen werden soll. Beide Methoden liefern einen int zurück, welcher der Anzahl der gelesenen Bytes entspricht.

Mit der Methode mark(int) wird eine Stelle in dem Stream markiert und mit reset() wird dann zu der letzten markierten Position zurückgesprungen, dies sollte aber nur benutzt werden, wenn die Methode markSupported() true zurückgibt.

Desweiteren besitzt die Klasse eine Methode close() welche immer aufgerufen werden sollte, wenn der Stream nicht mehr benötigt wird. Da diese Methode den Stream schließt und so die Datei wieder für andere Zugriffe freigibt, anderfalls kann die Datei nicht von anderen Prozessen geöffnet werden.

Bei den Streams der Standard-Java-API kann man mehrere Ebenen unterscheiden. Die unterste Ebene versucht die Daten aus einer Datei oder einer anderen Quelle auszulesen und gibt diese in dem meisten Fällen in byte-Array, diese Streams werden meistens direkt vom InputStream abgeleitet. Die nächste Ebene nimmt in dem meisten Fällen einen InpuStream als Quelle, aus der sie dann die Daten liest und je nach Verwendungszweck in verschiedenen Datentypen oder ähnlichem zurückgibt. Diese lassen sich oftmals auch wieder verschachteln und so ist eine Optimierung der Datenerfassung oder vereinfachtes Umwandeln oder Erfassen der Daten möglich.

Klassen die InputStream implementieren sind unter anderem FileInputStream, OubjectInputStream, BufferedInputStream, InputStreamReader und DataInputStream.

Weiterführende Artikel