Panduan untuk Java OutputStream

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan meneroka perincian mengenai OutputStream kelas Java . O utputStream adalah kelas abstrak. Ini berfungsi sebagai superclass untuk semua kelas yang mewakili aliran output byte.

Kami akan mengkaji apa maksud kata-kata seperti "output" dan "stream" ini dengan lebih terperinci semasa kami meneruskannya.

2. Pengenalan Ringkas ke Java IO

OutputStream adalah sebahagian dari Java IO API yang menentukan kelas yang diperlukan untuk melakukan operasi I / O di Java. Semua ini dibungkus dalam ruang nama java.io. Ini adalah salah satu pakej teras yang terdapat di Java sejak versi 1.0.

Memulai Java 1.4, kami juga memiliki Java NIO yang dikemas dalam namespace java.nio yang memungkinkan operasi input dan output yang tidak menyekat. Area fokus kami untuk artikel ini, bagaimanapun, adalah ObjectStream sebagai bagian dari Java IO.

Perincian yang berkaitan dengan Java IO dan Java NIO boleh didapati di sini.

2.1. Input dan Keluaran

Java IO pada dasarnya menyediakan mekanisme untuk membaca data dari sumber dan menulis data ke destinasi . Input mewakili sumber manakala output mewakili tujuan di sini.

Sumber dan destinasi ini boleh berupa Files, Paip hingga Sambungan Rangkaian.

2.2. Aliran

Java IO menyediakan konsep aliran yang pada dasarnya mewakili aliran data yang berterusan . Aliran dapat menyokong pelbagai jenis data seperti bait, watak, objek, dll.

Lebih-lebih lagi, sambungan ke sumber atau tujuan adalah apa yang ditunjukkan oleh aliran. Oleh itu, mereka datang sebagai InputStream atau OutputStream masing-masing.

3. Antara muka OutputStream

OutputStream menerapkan sekumpulan antara muka yang memberikan beberapa watak yang berbeza untuk subkelasnya. Mari kita lalui dengan cepat.

3.1. Boleh ditutup

Antaramuka Closeable menyediakan kaedah yang disebut close () yang menangani penutupan sumber atau tujuan data. Setiap pelaksanaan OutputStream mesti menyediakan pelaksanaan kaedah ini. Di sini mereka dapat melakukan tindakan untuk melepaskan sumber.

3.2. AutoTutup

Antara muka AutoCloseable juga menyediakan kaedah yang disebut close () dengan tingkah laku yang serupa dengan yang ada di Closeable . Walau bagaimanapun, dalam kes ini, kaedah close () dipanggil secara automatik ketika keluar dari blok sumber daya.

Maklumat lanjut mengenai sumber-sumber boleh didapati di sini.

3.3. Flushable

Antara muka Flushable menyediakan kaedah yang disebut flush () yang menangani data pembilasan ke suatu tujuan.

Pelaksanaan tertentu OutputStream mungkin memilih untuk menyangga byte yang ditulis sebelumnya untuk dioptimumkan, tetapi panggilan untuk menyiram () membuatnya segera menulis ke tujuan .

4. Kaedah dalam OutputStream

OutputStream mempunyai beberapa kaedah yang harus dilaksanakan oleh setiap kelas pelaksana untuk jenis data masing-masing.

Ini adalah selain daripada rapat () dan flush () kaedah yang ia mewarisi dari Closeable dan flushable muka.

4.1. tulis (int b)

Kita boleh menggunakan kaedah ini untuk menulis satu bait tertentu ke OutputStream . Oleh kerana argumen "int" terdiri daripada empat bait, setara dengan kontrak hanya bait pesanan rendah pertama ditulis dan baki tiga bait pesanan tinggi dan diabaikan:

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

Sekiranya kita memanggil kaedah ini dengan data sebagai "Hello World!", Hasilnya adalah fail dengan teks berikut:

W

Ini, seperti yang dapat kita lihat, adalah watak ketujuh dari rentetan yang diindeks keenam.

4.2. tulis (bait [] b, int mati, panjang int)

Versi kaedah penulisan () yang terlalu banyak ini ada untuk menulis sub-urutan susunan bait ke OutputStream .

Ia dapat menulis bilangan "panjang" bait dari tatasusunan bait seperti yang ditentukan oleh argumen bermula pada ofset yang ditentukan oleh "mati" ke OutputStream:

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); } }

Sekiranya kita memanggil kaedah ini dengan data yang sama seperti sebelumnya, kita akan mendapat teks berikut dalam fail output kita:

World

Ini adalah substring data kami bermula dari indeks lima dan terdiri daripada lima watak.

4.3. tulis (bait [] b)

Ini adalah satu lagi kaedah kaedah menulis () yang terlalu banyak yang dapat menulis keseluruhan susunan bait seperti yang ditentukan oleh argumen kepada OutputStream .

Ini mempunyai kesan yang sama dengan panggilan untuk menulis (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); } }

Apabila kita memanggil kaedah ini sekarang dengan data yang sama, kita mempunyai keseluruhan String dalam fail output kita:

Hello World!

5. Direct Subclasses of OutputStream

Now we'll discuss some of the direct known subclasses of OutputStream which individually represent a specific data type of which the OutputStream they define.

They define their own methods apart from implementing those inherited from OutputStream.

We won't go into the details of these subclasses.

5.1. FileOutputStream

As the name suggests, a FileOutputStream is an OutputStream to write data to a File. FileOutputStream, like any other OutputStream, can write a stream of raw bytes.

We have already examined different methods in FileOutputStream as part of the last section.

5.2. ByteArrayOutputStream

ByteArrayOutputStream is an implementation of OutputStream that can write data into a byte array. The buffer keeps growing as ByteArrayOutputStream writes data to it.

We can keep the default initial size of the buffer as 32 bytes or set a specific size using one of the constructors available.

The important thing to note here is that the method close() has practically no effect. The other methods in ByteArrayOutputStream can be safely called even after close() has been called.

5.3. FilterOutputStream

OutputStream primarily writes a byte stream to a destination, but it can as well transform the data before doing so. FilterOutputStream represents superclass of all such classes which perform a specific data transformation. FilterOutputStream is always constructed with an existing OutputStream.

Some of the examples of FilterOutputStream are BufferedOutputStream, CheckedOutputStream, CipherOutputStream, DataOutputStream, DeflaterOutputStream, DigestOutputStream, InflaterOutputStream, PrintStream.

5.4. ObjectOutputStream

ObjectOutputStream can write primitive data types and graphs of Java objects to a destination. We can construct an ObjectOutputStream using an existing OutputStream to write to a specific destination like File.

Please note that it is necessary for objects to implement Serializable for ObjectOutputStream to write them to a destination. You can find more details on Java Serialization here.

5.5. PipedOutputStream

A PipedOutputStream is useful to create a communication pipe. PipedOutputStream can write data which a connected PipedInputStream can read.

PipedOutputStream features a constructor to connect it with a PipedInputStream. Alternatively, we can do this later by using a method provided in PipedOutputStream called connect().

6. OutputStream Buffering

Input and output operations typically involve relatively expensive operations like disk access, network activity, etc. Performing this often can make a program less efficient.

We have “buffered streams” of data in Java to handle these scenarios. BufferedOutputStreamwrites data to a buffer instead which is flushed to the destination less often, when the buffer gets full, or the method flush() is called.

BufferedOutputStream extends FilterOutputStream discussed earlier and wraps an existing OutputStream to write to a destination:

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()); } } }

The critical point to note is that every call to write() for each data argument only writes to the buffer and does not result in a potentially expensive call to the File.

In the case above, if we call this method with data as “Hello”, “World!”, this will only result in data being written to the File when the code exits from the try-with-resources block which calls the method close() on the BufferedOutputStream.

This results in an output file with the following text:

Hello World!

7. Writing Text with OutputStreamWriter

A byte stream, as discussed earlier, represents raw data which may be a bunch of text characters. Now we can get the character array and perform the conversion to the byte array ourselves:

byte[] bytes = data.getBytes();

Java provides convenient classes to bridge this gap. For the case of OutputStream, this class is OutputStreamWriter. OutputStreamWriter wraps an OutputStream and can directly write characters to the desired destination.

We can also optionally provide the OutputStreamWriter with a character set for encoding:

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); } }

Sekarang seperti yang kita lihat, kita tidak perlu melakukan transformasi array karakter ke array byte sebelum menggunakan FileOutputStream. OutputStreamWriter melakukan ini dengan mudah untuk kita .

Tidak mengejutkan apabila kita memanggil kaedah di atas dengan data seperti "Hello World!", Ini menghasilkan fail dengan teks sebagai:

Hello World!

8. Kesimpulannya

Dalam artikel ini, kami membincangkan OutputStream kelas abstrak Java . Kami melalui antara muka yang diimplementasikan dan kaedah yang disediakannya.

Kemudian kami membincangkan beberapa sub-kelas OutputStream yang terdapat di Java. Kami akhirnya bercakap mengenai buffering dan aliran watak.

Seperti biasa, kod untuk contoh boleh didapati di GitHub.