1. OutputStreamKlasse

Wir haben erst kürzlich Eingabeströme untersucht. Es ist Zeit, über Ausgabeströme zu sprechen.

Die OutputStreamKlasse ist die übergeordnete Klasse für alle Klassen, die die Byte-Ausgabe unterstützen. Dies ist eine abstrakte Klasse, die für sich genommen nichts tut, aber für jeden Anlass Nachkommenklassen hat.

Es klingt äußerst kompliziert. Einfacher ausgedrückt: Diese Klasse arbeitet mit Bytes und nicht beispielsweise mit Zeichen oder anderen Datentypen. Und die Tatsache, dass es abstrakt ist, bedeutet, dass wir es normalerweise nicht verwenden, sondern eine seiner Nachkommenklassen. Zum Beispiel FileOutputStreamund dergleichen.

Aber zurück zur OutputStreamKlasse. Diese Klasse verfügt über Methoden, die alle ihre Nachkommenklassen implementieren müssen. Hier sind die wichtigsten:

Methoden Beschreibung
void write(int b)
Schreibt ein Byte (kein int) in den Stream.
void write(byte[] buffer)
Schreibt ein Array von Bytes in den Stream
void write(byte[] buffer, off, len)
Schreibt einen Teil eines Byte-Arrays in den Stream
void flush()
Schreibt alle im Puffer gespeicherten Daten in den Stream
void close()
Schließt den Stream

Wenn Sie ein Objekt einer Klasse erstellen, die erbt InputStream, geben Sie normalerweise ein Quellobjekt an, InputStreamaus dem Daten gelesen werden. Wenn Sie ein Objekt einer Klasse erstellen, die erbt OutputStream, geben Sie normalerweise auch das Zielobjekt oder den Zielstream an, in den die Daten geschrieben werden.

Gehen wir kurz alle Methoden der OutputStreamKlasse durch:

write(int b)Methode

Diese Methode schreibt ein Byte (kein int) in den Ausgabestream. Der übergebene Wert wird in ein Byte umgewandelt und die ersten drei Bytes des Int werden verworfen.

write(byte[] buffer)Methode

Schreibt das angegebene Byte-Array in den Ausgabestream. Das ist es.

write(byte[] buffer, int offset, int length)Methode

Schreibt einen Teil des übergebenen Byte-Arrays in den Ausgabestream. Die Offset-Variable gibt den Index des ersten Elements des Arrays an und lengthist die Länge der zu schreibenden Teilmenge.

flush()Methode

Die flush()Methode wird verwendet, um zu erzwingen, dass alle möglicherweise im aktuellen Stream gepufferten Daten in den Zielstream geschrieben werden. Dies ist relevant, wenn Pufferung und/oder mehrere in einer Kette angeordnete Stream-Objekte verwendet werden.

close()Methode

Schreibt alle ungeschriebenen Daten in das Zielobjekt. close()Wenn Sie einen Block verwenden, muss die Methode nicht aufgerufen werden try-with-resources.

Beispiel für das Kopieren einer Datei

Code Notiz
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileInputStream input = new FileInputStream(src);
FileOutputStream output = new FileOutputStream(dest))
{
   byte[] buffer = new byte[65536]; // 64Kb
   while (input.available() > 0)
   {
      int real = input.read(buffer);
      output.write(buffer, 0, real);
   }
}



InputStreamzum Lesen aus einer Datei
OutputStreamzum Schreiben in eine Datei

Puffer, in den wir die Daten einlesen werden
Solange Daten im Stream vorhanden sind

Daten in den Puffer lesen
Die Daten aus dem Puffer in den zweiten Stream schreiben

2. WriterKlasse

Die WriterKlasse ist genau die gleiche wie die OutputStreamKlasse, hat aber noch einmal einen Unterschied: Sie arbeitet mit Zeichen ( char) statt mit Bytes.

Dies ist eine abstrakte Klasse: Sie können keine Objekte der WriterKlasse erstellen. Ihr Hauptziel besteht darin, eine gemeinsame Elternklasse für Hunderte von Nachkommenklassen zu sein und ihnen gemeinsame Methoden für die Arbeit mit Zeichenströmen zur Verfügung zu stellen.

Methoden der WriterKlasse (und aller ihrer Nachkommenklassen):

Methoden Beschreibung
void write(int b)
Schreibt ein Zeichen (kein int) in den Stream.
void write(char[] buffer)
Schreibt ein Array von Zeichen in den Stream
void write(char[] buffer, off, len)
Schreibt einen Teil eines Zeichenarrays in den Stream
void write(String str)
Schreibt einen String in den Stream
void write(String str, off, len)
Schreibt einen Teil einer Zeichenfolge in den Stream
void flush()
Schreibt alle im Puffer gespeicherten Daten in den Stream
void close()
Schließt den Stream

Die Methoden sind den Methoden der OutputStreamKlasse sehr ähnlich, arbeiten jedoch mit Zeichen statt mit Bytes.

Beschreibung der Methoden:

write(int b)Methode

Diese Methode schreibt ein einzelnes Zeichen ( char— kein int) in den Ausgabestream. Der übergebene Wert wird in a umgewandelt charund die ersten beiden Bytes werden verworfen.

write(char[] buffer)Methode

Schreibt das angegebene Zeichenarray in den Ausgabestream.

write(char[] buffer, int offset, int length)Methode

Schreibt einen Teil des übergebenen Zeichenarrays in den Ausgabestream. Die offsetVariable gibt den Index des ersten Elements des Arrays an und lengthist die Länge der zu schreibenden Teilmenge.

write(String str)Methode

Schreibt die angegebene Zeichenfolge in den Ausgabestream.

write(String str, int offset, int length)Methode

Schreibt einen Teil der angegebenen Zeichenfolge in den Ausgabestream: Die Zeichenfolge wird in ein Array von Zeichen konvertiert. Die offsetVariable gibt den Index des ersten Elements des Arrays an und lengthist die Länge der zu schreibenden Teilmenge.

flush()Methode

Die flush()Methode wird verwendet, um zu erzwingen, dass alle möglicherweise im aktuellen Stream gepufferten Daten in den Zielstream geschrieben werden. Dies ist relevant, wenn Pufferung und/oder mehrere in einer Kette angeordnete Stream-Objekte verwendet werden.

close()Methode

Schreibt alle ungeschriebenen Daten in das Zielobjekt. close()Wenn Sie einen Block verwenden, muss die Methode nicht aufgerufen werden try-with-resources.

Beispiel für ein Programm, das eine Textdatei kopiert:

Code Notiz
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileReader reader = new FileReader(src);
FileWriter writer = new FileWriter(dest))
{
   char[] buffer = new char[65536]; // 128Kb
   while (reader.ready())
   {
      int real = reader.read(buffer);
      writer.write(buffer, 0, real);
   }
}



Readerzum Lesen aus einer Datei
Writerzum Schreiben in eine Datei

Puffer, in den wir die Daten einlesen werden
Solange Daten im Stream vorhanden sind

Daten in einen Puffer lesen
Die Daten aus dem Puffer in den zweiten Stream schreiben

StringWriterKlasse

Es gibt eine weitere interessante Klasse, die die Klasse erbt Writer: Sie heißt StringWriter. Es enthält eine veränderbare Zeichenfolge – ein StringBufferObjekt. Und jedes Mal, wenn Sie etwas in das StringWriterObjekt „schreiben“, wird der Text einfach zu seinem internen Puffer hinzugefügt.

Beispiel:

Code Notiz
StringWriter writer = new StringWriter();
writer.write("Hello");
writer.write(String.valueOf(123));

String result = writer.toString();
Es wird ein Zielzeichenstrom ( StringWriter) erstellt.
Eine Zeichenfolge wird in den Puffer im Inneren geschrieben. StringWriter
Eine Zeichenfolge wird in den Puffer im Inneren geschrieben. StringWriter

Konvertieren des Inhalts eines Objekts in eine Zeichenfolge

In diesem Fall StringWriterist die Klasse im Wesentlichen ein Wrapper für die StringBufferKlasse, aber die StringWriterKlasse ist ein Nachkomme der WriterStream-Klasse und kann in Ketten von Stream-Objekten verwendet werden. Dies ist in der Praxis eine ziemlich nützliche Eigenschaft.



3. PrintStreamKlasse

Ausgabe-Stream-Klassen können auch in eine Kette mit Zwischen-Streams eingefügt werden, die Daten in den an sie übergebenen Ziel-Stream schreiben. Die Gesamtansicht des Zusammenspiels dieser Streams sieht folgendermaßen aus:

PrintStream-Klasse

Der interessanteste und vielseitigste aller Zwischenausgabeströme ist PrintStream. Es verfügt über Dutzende Methoden und bis zu 12 Konstruktoren.

Die PrintStreamKlasse erbt die FilterOutputStreamKlasse, die erbt OutputStream. Das bedeutet, dass die PrintStreamKlasse zusätzlich zu ihren eigenen Methoden über alle Methoden der übergeordneten Klassen verfügt . Hier sind die interessantesten:

Methoden Beschreibung
void print(obj)
Konvertiert das übergebene Objekt in einen String und gibt ihn an den Zielstream aus.
void println(obj)
Konvertiert das übergebene Objekt in einen String und gibt ihn an den Zielstream aus. Fügt am Ende einen Zeilenumbruch ein
void println()
Gibt ein Zeilenumbruchzeichen an den Zielstream aus
PrintStream format(String format, args...)
Konstruiert und gibt eine Zeichenfolge basierend auf der Formatzeichenfolge und den übergebenen Argumenten aus; ähnlich der String.format()Methode

Und wo sind diese Dutzenden von Methoden, fragen Sie?

Nun, es gibt viele Varianten der print()und- println()Methoden mit unterschiedlichen Parametern. Sie können in dieser Tabelle zusammengefasst werden.

Wir gehen nicht näher auf diese Methoden ein, da Sie sie bereits gut kennen. Können Sie erraten, worauf ich hinaus will?

Erinnern Sie sich System.out.println()? Aber es kann in zwei Zeilen geschrieben werden:

Code Konsolenausgabe
PrintStream stream = System.out;
stream.println("Hello!");
Hello!

Unser Lieblingsbefehl ist ein Aufruf der Methode für die statische Variable der Klasse. Und der Typ dieser Variablen ist .System.out.println()println()outSystemPrintStream

In vielen CodeGym-Levels und in fast jeder Aufgabe haben Sie Methoden der PrintStreamKlasse aufgerufen, ohne es zu wissen!

Praktischer Nutzen

Java hat diese interessante Klasse namens ByteArrayOutputStream, bei der es sich um ein dynamisch wachsendes Byte-Array handelt, das erbt OutputStream.

Ein ByteArrayOutputStreamObjekt und PrintStreamein Objekt können wie folgt verkettet werden:

Code Beschreibung
ByteArrayOutputStream baos = new ByteArrayOutputStream();

try(PrintStream stream = new PrintStream(baos))
{
   stream.println("Hello");
   stream.println(123);
}

String result = baos.toString();

System.out.println(result);
Erstellen Sie einen Schreibpuffer im Speicher.

Wickeln Sie den Puffer in ein PrintStreamObjekt

. Schreiben Sie Daten in die Konsole.



Konvertieren Sie das Array in einen String!

Konsolenausgabe:
Hello!
123