09.03.03 java.io.OutputStream

Der java.io.OutputStream ist das Gegenstück zum java.io.InputStream, der im vorhergehenden Kapitel behandelt wurde. Somit stellt der OutputStream die Basisklasse aller schreibenden Datenströme dar. Das beinhaltet u. a. das Schreiben von binären Daten auf die Festplatte (z. B. Bilder und Dateien), in das Netzwerk (Datenübertragung zwischen zwei Computern), oder einer Ausgabe auf der Konsole.

Mit dem bekanntesten OutputStream haben Sie sich bereits ausführlich beschäftigt. Es handelt sich hierbei um einen java.io.PrintStream, der über einen java.io.FilterOutputStream indirekt von java.io.OutputStream erbt. Diesen finden Sie als öffentlich, statisches Attribut in der Klasse java.lang.System und ermöglicht es Ihnen, Text auf der Standardausgabe (in den meisten Fällen der Konsole) auszugeben.

System.out.println("Ich bin die Standardausgabe");

Wie Sie der API-Dokumentation entnehmen können, handelt es sich beim java.io.OutputStream um eine abstrakte Klasse. Sie kann also nicht sofort verwendet und über das Schlüsselwort new instanziiert werden. Stattdessen wird eine Kinderklasse benötigt, die von java.io.OutputStream erbt und die fehlenden Methoden implementiert. Ebenfalls wird aus der Dokumentation erkenntlich, dass die einzige abstrakte Methode write(int b) lautet. Sehen Sie sich aber zuerst einmal alle Methoden dieser abstrakten Klasse an:

  • close() – Ebenso wie beim InputStream schließt diese Methode wieder alle Verbindungen, die der OutputStream geöffnet/benötigt hat. Meistens ist ein ordentliches Schließen bei einem OutputStream noch wichtiger als bei einem InputStream, da ein schreibender Vorgang vom Ziel (z. B. eine Datei auf dem Computer) oftmals einen exklusiveren Zugriff verlangt, als beim Lesen.
  • flush() – Aus Geschwindigkeitsgründen können OutputStreams die zu schreibenden Bytes zwischenspeichern (puffern) und – sobald genügend Bytes vorhanden sind – diese erst zu einem späteren Zeitpunkt an das Ziel weiterleiten. Ein flush() bewirkt, dass der OutputStream alle gepufferten Bytes an das Ziel des Streams sendet.
  • write(byte[] b) – Sendet/schreibt die übergebenen Bytes an/in das Ziel des Streams
  • write(byte[] b, int off, int len) – Funktionsweise wie write(byte[] b), nur dass spezifiziert werden kann, welcher Teil (off Anfangspunkt, len Anzahl der zu schreibenden Bytes) des byte-Arrays geschrieben werden soll.
  • write(int b) – Schreibt ein einzelnes Byte in das Ziel des Streams.

Wie beim InputStream sollte es auch beim OutputStream relativ einleuchtend sein, warum nur eine Methode überschrieben werden muss. write(int b) ist für das Schreiben in das jeweils spezifische Ziel zuständig. Da dieses Ziel von der konkreten Implementierung des OutputStreams abhängig ist, muss diese Methode auch zwingend individuell implementiert werden hotslotsonline.net. Die Realisierung der restlichen Methoden geschieht über ein Standardverhalten bzw. aufbauend auf write(int b). Werfen Sie zum besseren Verständnis einen Blick in den Quellcode von java.io.OutputStream:

package java.io;

public abstract class OutputStream implements Closeable, Flushable {

  public abstract void write(int b) throws IOException;

  public void write(byte b[]) throws IOException {
	write(b, 0, b.length);
  }

  public void write(byte b[], int off, int len) throws IOException {
	if (b == null) {
	  throw new NullPointerException();
	} else if ((off < 0) || (off > b.length) || (len < 0) ||
		   ((off + len) > b.length) || ((off + len) < 0)) {
	  throw new IndexOutOfBoundsException();
	} else if (len == 0) {
	  return;
	}
	for (int i = 0 ; i < len ; i++) {
	  write(b&#91;off + i&#93;);
	}
  }

  public void flush() throws IOException {
  }

  public void close() throws IOException {
  }
}&#91;/sourcecode&#93;

Die beiden anderen <code>write</code>-Methoden rufen entweder einander, oder die zu implementierende <code>write(int b)</code> Methode auf. Aufgrund der Realisierung dieser Methoden ist mehr als ein leeres <code>flush()</code> und <code>close()</code> nicht nötig.

Sehen wir uns nun noch eine einfache Beispielimplementierung des <code>java.io.OutputStreams</code> an: Einen selbst programmierten <code><strong>StringBuilderOutputStream</strong></code>, der die Bytes direkt in einen <code>StringBuilder</code> schreibt.

package de.jbb.io;

import java.io.IOException;
import java.io.OutputStream;

public class StringBuilderOutputStream extends OutputStream {

  private StringBuilder target;

  public StringBuilderOutputStream(StringBuilder target) {
    this.target = target;
  }

  @Override
  public void write(int b) throws IOException {
    this.target.append((char)b);
  }
}

Zum Testen können Sie folgende Zeilen verwenden:

StringBuilder myBuild = new StringBuilder();
OutputStream os = new StringBuilderOutputStream(myBuild);
os.write("Hallo StringBuilder!".getBytes());
System.out.println(myBuild.toString());

Ein möglicher Einsatzort für den StringBuilderOutputStream sind externe Methoden, die einen OutputStream erwarten, deren Ergebnis Sie aber gleich im Programm als String(Builder) weiterverarbeiten möchten.

One Reply to “09.03.03 java.io.OutputStream”

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.