Anleitung zu Java OutputStream

Anleitung zu Java OutputStream

 

1. Überblick

In diesem Tutorial werden Details zur Java-KlasseOutputStreamuntersucht. OutputStream ist eine abstrakte Klasse. Dies dient alsthe superclass for all classes representing an output stream of bytes.

Wir werden untersuchen, was diese Wörter wie "Ausgabe" und "Stream" im weiteren Verlauf genauer bedeuten.

2. Kurze Einführung in Java IO

OutputStream is part of the Java IO API, das Klassen definiert, die zum Ausführen von E / A-Operationen in Java erforderlich sind. Diese sind alle im Namespacejava.iogepackt. Dies ist eines der Kernpakete, die in Java seit Version 1.0 verfügbar sind.

Ab Java 1.4 haben wir auch Java NIO im Namespacejava.nio gepackt, was nicht blockierende Eingabe- und Ausgabeoperationen ermöglicht. Unser Fokusbereich für diesen Artikel ist jedochObjectStream als Teil von Java IO.

Details zu Java IO und Java NIO finden Sie unterhere.

2.1. Ein- und Ausgang

Java IO bietet grundsätzlicha mechanism to read data from a source and write data to a destination. Die Eingabe stellt die Quelle dar, während die Ausgabe hier das Ziel darstellt.

Diese Quellen und Ziele können Dateien, Pipes und Netzwerkverbindungen sein.

2.2. Streams

Java IO bietet das Konzept vonstreams which basically represents a continuous flow of data. Streams können viele verschiedene Datentypen wie Bytes, Zeichen, Objekte usw. unterstützen.

Darüber hinaus repräsentiert ein Stream die Verbindung zu einer Quelle oder einem Ziel. Sie kommen daher entweder alsInputStream oder alsOutputStream.

3. Schnittstellen vonOutputStream

OutputStream implementiert eine Reihe von Schnittstellen, die ihren Unterklassen einen bestimmten Charakter verleihen. Lassen Sie uns sie schnell durchgehen.

3.1. Closeable

Die SchnittstelleCloseable bietet eine Methode namensclose() whichhandles closing a source or a destination of data.. Jede Implementierung vonOutputStream muss eine Implementierung dieser Methode bereitstellen. Hier können sie Aktionen ausführen, um Ressourcen freizugeben.

3.2. AutoCloseable

Die SchnittstelleAutoCloseable bietet auch eine Methode namensclose() mit einem ähnlichen Verhalten wie die inCloseable. In diesem Fall sind jedoch diemethod close() is automatically called when exiting a try-with-resource block.

Weitere Details zu Try-with-Resource finden Sie unterhere.

3.3. Flushable

Die SchnittstelleFlushable bietet eine Methode namensflush(), mit der Daten an ein Ziel gesendet werden.

Eine bestimmte Implementierung vonOutputStream kann sich dafür entscheiden, zuvor geschriebene Bytes zu puffern, um sie zu optimieren, abera call to flush() makes it write to the destination immediately.

4. Methoden in OutputStream

OutputStream verfügt über mehrere Methoden, die jede implementierende Klasse für ihren jeweiligen Datentyp implementieren muss.

Dies sind abgesehen von den Methodenclose() undflush(), die von den SchnittstellenCloseable undFlushable geerbt werden.

4.1. write(int b)

Wir können diese Methode fürwrite one specific byte to the OutputStream verwenden. Da das Argument "int" aus vier Bytes besteht, wird als Teil des Vertrags nur das erste Byte niedriger Ordnung geschrieben und die restlichen drei Bytes hoher Ordnung ignoriert:

public static void fileOutputStreamByteSingle(String file, String data) throws IOException {
    byte[] bytes = data.getBytes();
    try (OutputStream out = new FileOutputStream(file)) {
        out.write(bytes[6]);
    }
}

Wenn wir diese Methode mit Daten als "Hello World!" Aufrufen, erhalten wir als Ergebnis eine Datei mit dem folgenden Text:

W

Dies ist, wie wir sehen können, das siebte Zeichen der Zeichenfolge, die mit dem sechsten Index versehen ist.

4.2. write(byte[] b, int off, int length)

Diese überladene Version derwrite()-Methode ist fürwrite a sub-sequence of the byte array to the OutputStream verfügbar.

Es kann die Anzahl der Bytes "Länge" aus dem Byte-Array schreiben, wie durch das Argument angegeben, beginnend mit einem durch "Aus" bestimmten Versatz inOutputStream:

public static void fileOutputStreamByteSubSequence(
  String file, String data) throws IOException {
    byte[] bytes = data.getBytes();
    try (OutputStream out = new FileOutputStream(file)) {
        out.write(bytes, 6, 5);
    }
}

Wenn wir diese Methode jetzt mit denselben Daten wie zuvor aufrufen, erhalten wir den folgenden Text in unserer Ausgabedatei:

World

Dies ist die Teilzeichenfolge unserer Daten, die mit Index fünf beginnt und aus fünf Zeichen besteht.

4.3. write(byte[] b)

Dies ist eine weitere überladene Version der Methodewrite(), diewrite an entire byte array kann, wie durch das Argument fürOutputStream angegeben.

Dies hat den gleichen Effekt wie ein Aufruf vonwrite(b, 0, b.lengh):

public static void fileOutputStreamByteSequence(String file, String data) throws IOException {
    byte[] bytes = data.getBytes();
    try (OutputStream out = new FileOutputStream(file)) {
        out.write(bytes);
    }
}

Wenn wir diese Methode jetzt mit denselben Daten aufrufen, haben wir die gesamtenString in unserer Ausgabedatei:

Hello World!

5. Direkte Unterklassen vonOutputStream

Jetzt werden wir einige der direkt bekannten Unterklassen vonOutputStream diskutieren, die einzeln einen bestimmten Datentyp darstellen, dessenOutputStream sie definieren.

Sie definieren ihre eigenen Methoden, abgesehen von der Implementierung der vonOutputStream geerbten.

Wir werden nicht auf die Details dieser Unterklassen eingehen.

5.1. FileOutputStream

Wie der Name schon sagt, ist aFileOutputStreaman OutputStream to write data to a File. FileOutputStream kann wie jedes andereOutputStream einen Strom von Rohbytes schreiben.

Wir haben bereits im letzten Abschnitt verschiedene Methoden inFileOutputStream untersucht.

5.2. ByteArrayOutputStream

ByteArrayOutputStream ist einimplementation of OutputStream that can write data into a byte array. Der Puffer wächst weiter, wennByteArrayOutputStream Daten in ihn schreibt.

Wir können die anfängliche Standardgröße des Puffers auf 32 Byte belassen oder eine bestimmte Größe mit einem der verfügbaren Konstruktoren festlegen.

Wichtig hierbei ist, dass die Methodeclose() praktisch keine Wirkung hat. Die anderen Methoden inByteArrayOutputStream können auch nach dem Aufruf vonclose() sicher aufgerufen werden.

5.3. FilterOutputStream

OutputStream schreibt in erster Linie einen Byte-Stream an ein Ziel, kann die Daten jedoch auch vorher transformieren. FilterOutputStream steht fürsuperclass of all such classes which perform a specific data transformation. FilterOutputStream wird immer mit einem vorhandenenOutputStream konstruiert.

Einige Beispiele fürFilterOutputStream sindBufferedOutputStream,CheckedOutputStream,CipherOutputStream,DataOutputStream,DeflaterOutputStream,DigestOutputStream,InflaterOutputStream) s,PrintStream.

5.4. ObjectOutputStream

ObjectOutputStream kannwrite primitive data types and graphs of Java objects zu einem Ziel führen. Wir können einObjectOutputStream unter Verwendung eines vorhandenenOutputStream erstellen, um in ein bestimmtes Ziel wie Datei zu schreiben.

Bitte beachten Sie, dass ObjekteSerializable fürObjectOutputStream implementieren müssen, um sie an ein Ziel zu schreiben. Weitere Informationen zu Java Serializationhere finden Sie hier.

5.5. PipedOutputStream

APipedOutputStream istuseful to create a communication pipe. PipedOutputStream können Daten schreiben, die ein verbundenerPipedInputStream lesen kann.

PipedOutputStream verfügt über einen Konstruktor, der es mitPipedInputStream verbindet. Alternativ können wir dies später tun, indem wir eine inPipedOutputStream bereitgestellte Methode verwenden, dieconnect() heißt.

6. OutputStream Pufferung

Eingabe- und Ausgabevorgänge umfassen normalerweise relativ teure Vorgänge wie Festplattenzugriff, Netzwerkaktivität usw. Wenn Sie dies häufig ausführen, kann dies die Effizienz eines Programms beeinträchtigen.

Wir haben Datenströme in Java gepuffert, um diese Szenarien zu handhaben. BufferedOutputStreamwrites data to a buffer instead which is flushed to the destination less often, wenn der Puffer voll ist oder die Methodeflush() aufgerufen wird.

BufferedOutputStream erweitertFilterOutputStream, die zuvor besprochen wurden, und umschließt ein vorhandenesOutputStream , um an ein Ziel zu schreiben:

public static void bufferedOutputStream(
  String file, String ...data) throws IOException {

    try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file))) {
        for(String s : data) {
            out.write(s.getBytes());
            out.write(" ".getBytes());
        }
    }
}

Der kritische Punkt ist, dass jeder Aufruf vonwrite() für jedes Datenargument nur in den Puffer schreibt und nicht zu einem potenziell teuren Aufruf der Datei führt.

Wenn wir im obigen Fall diese Methode mit Daten als "Hallo", "Welt!" Aufrufen, werden Daten nur dann in die Datei geschrieben, wenn der Code aus dem Try-with-Resources-Block beendet wird, der die Methode{'t0': 'close()', 't1': 'BufferedOutputStream'}ufruft (t0) s aufBufferedOutputStream.

Dies führt zu einer Ausgabedatei mit dem folgenden Text:

Hello World!

7. Schreiben von Text mitOutputStreamWriter

Ein Bytestrom stellt, wie bereits erläutert, Rohdaten dar, die aus einer Reihe von Textzeichen bestehen können. Jetzt können wir das Zeichenarray abrufen und die Konvertierung in das Byte-Array selbst durchführen:

byte[] bytes = data.getBytes();

Java bietet praktische Klassen, um diese Lücke zu schließen. Für den Fall vonOutputStream ist diese KlasseOutputStreamWriter. OutputStreamWriter wraps an OutputStream and can directly write characters to the desired destination.

Optional können wir auchOutputStreamWriter mit einem Zeichensatz für die Codierung bereitstellen:

public static void outputStreamWriter(String file, String data) throws IOException {
    try (OutputStream out = new FileOutputStream(file);
        Writer writer = new OutputStreamWriter(out,"UTF-8")) {
        writer.write(data);
    }
}

Wie wir jetzt sehen können, müssen wir die Transformation des Zeichenarrays in das Bytearray nicht durchführen, bevor wirFileOutputStream.OutputStreamWriter verwenden. Dies ist für uns. bequem

Es ist nicht überraschend, wenn wir die obige Methode mit Daten wie „Hello World!“ Aufrufen. Dies führt zu einer Datei mit folgendem Text:

Hello World!

8. Fazit

In diesem Artikel haben wir die abstrakte Java-KlasseOutputStream besprochen. Wir haben die implementierten Schnittstellen und die bereitgestellten Methoden durchgesehen.

Anschließend haben wir einige der in Java verfügbaren Unterklassen vonOutputStreambesprochen. Wir sprachen schließlich über Pufferung und Zeichenströme.

Wie immer ist der Code für die Beispieleover on GitHub verfügbar.