Java IO programming -- character stream and byte stream

Posted by mikesmith76 on Sat, 02 Nov 2019 18:44:50 +0100

In the java.io package, the File class is the only program processing class related to the File itself, but the File can only operate the File itself and not the content of the File, or the core meaning of IO operation in actual development is: input and output operation. For a program, the input and output may come from different environments. For example, when a computer is connected to the server for browsing, in fact, the client sends a message, and then the server receives the message and processes the response.

 

 

For the server or the client, what is actually passed is a form of data flow processing, and the so-called data flow refers to byte data. There are two types of support for this flow processing form in the java.io package:

 

Byte processing stream: OutputStream (output byte stream), InputStream (input byte stream);

 

Character processing stream: Writer (output character stream), Reader (input character stream);

All flow operations should be carried out in the following unified steps. Take the flow of file processing as an example:

 

If you want to read and write files, you must find a File path through the File class;

 

Instantiate the parent object through the subclass of byte stream or character stream;

 

Use byte stream or character stream to realize data input and output operation;

 

Stream operation belongs to resource operation. Resource operation must be closed;

 

1. Byte output stream: OutputStream

 

Byte data is mainly implemented by byte type. When outputting byte content, OutputStream class can be used. The basic definition of this class is as follows:

public abstract class OutputStream extends Object implements Closeable, Flushable

First of all, it can be found that this class implements two interfaces, so the basic correspondence is as follows:

 

 

Closeable:

Flushable:

public interface Closeable extends AutoCloseable {public void close​() throws Exception;}

public interface Flushable{public void flush​() throws IOException;}

 

 

The OutputStream class defines a common output operation standard, in which there are three content output methods.

No

Method name

type

describe

01

public abstract void write​(int b) throws IOException

ordinary

Output single byte data

02

public void write​(byte[] b) throws IOException

ordinary

Output a set of byte data

03

public void write​(byte[] b,int off,int len) throws IOException

ordinary

Output partial byte data

But one of the core problems we need to pay attention to is that the OutputStream class is an abstract class after all. If this abstract class wants to obtain the instantiated object, it should be completed through the upward transformation of the subclass instance according to the traditional understanding. If the file processing operation is going to be carried out now, the FileOutputStream subclass can be used:

Because the processing relationship of upward transformation needs to take place in the end, the focus of the core of the FileOutputStream subclass at this time can be placed on the construction method:

Construction method of [overwrite]: public FileOutputStream (File file) throws FileNotFoundException;

 

[append] construction method: public FileOutputStream (File file,boolean append) throws FileNotFoundException;

Example: using the OutputStream class to output content

 1 import java.io.File;
 2 import java.io.FileOutputStream;
 3 import java.io.OutputStream;
 4 public class JavaAPIDemo {
 5     public static void main(String[] args) throws Exception {
 6         File file = new File("D:" + File.separator + "hello" + 
 7             File.separator + "mldn.txt");             // 1,Specifies the path to the file to operate on
 8         if (!file.getParentFile().exists()) {        // file does not exist
 9             file.getParentFile().mkdirs() ;         // Create parent directory
10         }
11         OutputStream output = new FileOutputStream(file) ; // 2,Instantiation by subclass
12         String str = "www.mldn.cn" ; // File content to export
13         output.write(str.getBytes()); // 3,Change string to byte array and output
14         output.close(); // 4,close resource
15     }
16 }
JavaAPIDemo

This program uses the most standard form to realize the output operation processing. In the overall processing, only the parent directory of the file is created, but no file is created. After execution, it will be found that the file can automatically help the user create. In addition, we need to remind that since the OutputStream subclass also belongs to the subclass of the autocolosable interface, we can also simplify the use of the close() method.

Example: automatic shutdown processing

 1 import java.io.File;
 2 import java.io.FileOutputStream;
 3 import java.io.IOException;
 4 import java.io.OutputStream;
 5 public class JavaAPIDemo {
 6     public static void main(String[] args) throws Exception {
 7         File file = new File("D:" + File.separator + "hello" + File.separator + "pluto.txt"); // 1,Specifies the path to the file to operate on
 8         if (!file.getParentFile().exists()) { // file does not exist
 9             file.getParentFile().mkdirs(); // Create parent directory
10         }
11         try (OutputStream output = new FileOutputStream(file, true)) {//true Indicates additional data
12             String str = "www.cnblogs.com\r\n"; // File content to export
13             output.write(str.getBytes()); // 3,Change string to byte array and output
14         } catch (IOException e) {
15             e.printStackTrace(); 
16         }
17     }
18 }
JavaAPIDemo

Whether to use automatic shutdown depends on the overall structure of the project. In addition, it needs to be reminded that the entire program finally outputs a set of byte data, but do not forget that there are three output methods defined in the OutputStream class.

 

2. Byte input stream: InputStream

A stream corresponding to OutputStream class is byte input stream. InputStream class mainly implements byte data reading, which is defined as follows:

public abstract class InputStream extends Object implements Closeable

The following core methods are defined in the InputStream class:

No

Method name

type

describe

01

public abstract int read​()

throws IOException

ordinary

Read single byte data, if it has been read to the end now, return - 1

02

public int read​(byte[] b) throws IOException

ordinary

Read a set of byte data and return the number of reads. If no data has been read to the end, return - 1

03

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

ordinary

Read a set of byte data (only part of the array)

  

 

 

InputStream class belongs to an abstract class. At this time, you should rely on its subclass to instantiate objects. If you want to read from a file, you must use the FileInputStream subclass. For subclasses, only the instantiation of the parent class object is concerned.

Construction method: public FileInputStream (File file) throws FileNotFoundException;

 

 1 import java.io.File;
 2 import java.io.FileInputStream;
 3 import java.io.InputStream;
 4 public class JavaAPIDemo {
 5     public static void main(String[] args) throws Exception {
 6         File file = new File("D:" + File.separator + "hello" + File.separator + "mldn.txt");
 7         InputStream input = new FileInputStream(file) ;
 8         byte data [] = new byte [1024] ; // Open a buffer to read data
 9         int len = input.read(data) ; // Read data, save all data in byte array, return the number of reads,If mldn.txt If the length in the file is greater than 1024, only 1024 bytes of information will be read
10         System.out.println("[" + new String(data, 0, len) + "]");
11         input.close();
12     }
13 }
JavaAPIDemo

The most troublesome problem in byte input stream is that when using read() method to read, only byte array can be received.

Note that a new method has been added to InputStream class since JDK 1.9: public byte[] readAllBytes() throws IOException;

 1 import java.io.File;
 2 import java.io.FileInputStream;
 3 import java.io.InputStream;
 4 public class JavaAPIDemo {
 5     public static void main(String[] args) throws Exception {
 6         File file = new File("D:" + File.separator + "hello" + File.separator + "mldn.txt");
 7         InputStream input = new FileInputStream(file) ;
 8         byte data [] = input.readAllBytes() ; // Read all data
 9         System.out.println("[" + new String(data) + "]");
10         input.close();
11     }
12 }
JavaAPIDemo

If the content to be read is very large now, this kind of reading will directly crash the program. If you want to use it, try not to exceed 10KB.

 

3. Character output stream: Writer

When OutputStream byte output stream is used for data output, byte type data is used. In many cases, string output is more convenient. So for java.io package, character output stream is introduced in JDK 1.1: Writer. The definition of this class is as follows:

public abstract class Writer  extends Object implements Appendable, Closeable, Flushable

  

 

 

 

There are many output operation methods provided in the Writer class, focusing on two aspects:

Output character array: public void write (char[] cbuf) throws IOException;

Output string: public void write (String str) throws IOException;

Example: using Writer output

 1 import java.io.File;
 2 import java.io.FileWriter;
 3 import java.io.Writer;
 4 public class JavaAPIDemo {
 5     public static void main(String[] args) throws Exception {
 6         File file = new File("D:" + File.separator + "hello" + File.separator + "mldn.txt");
 7         if (!file.getParentFile().exists()) {
 8             file.getParentFile().mkdirs(); // Parent directory must exist
 9         }
10         Writer out = new FileWriter(file) ; 
11         String str = "www.mldn.cn" ;
12         out.write(str); 
13         out.close();
14     }
15 }
JavaAPIDemo
JavaAPIDemo

The biggest advantage of using writer output is that it can be done directly with strings. Writer is a character stream. The advantage of character processing lies in Chinese data.  

 

4. Character input stream: Reader

 

Reader is a type of character input stream. It belongs to an abstract class. The definition of this class is as follows:

public abstract class Reader extends Object implements Readable, Closeable

  

 

 

 

The Reader class does not provide the input processing operation with the whole string like the Writer class. Only character data can be used to receive:

Receive data: public int read (char[] cbuf) throws IOException;

Example: data reading

 1 import java.io.File;
 2 import java.io.FileReader;
 3 import java.io.Reader;
 4 public class JavaAPIDemo {
 5     public static void main(String[] args) throws Exception {
 6         File file = new File("D:" + File.separator + "hello" + File.separator + "mldn.txt");
 7         if (file.exists()) {    // Read if file exists
 8             Reader in = new FileReader(file) ;
 9             char data[] = new char[1024];
10             int len = in.read(data) ;
11             System.out.println("Read content:" + new String(data,0,len));
12             in.close();
13         }
14     }
15 }
JavaAPIDemo

When the character stream is read, the processing operation can only be implemented in the form of an array.

 

5. Difference between byte stream and character stream

Now through a series of analysis, we can know the basic operation of byte stream and character stream. However, there are still differences between the two kinds of streams. We will focus on the analysis of the output processing operation. At the end of using OutputStream and Writer output, we found that the close() method was used for closing.

When using the OutputStream class output, if the close() method is not used to close the output stream, normal output can still be achieved. However, if the close() method is not used to close the output stream when using the Writer, then the content will not be able to output at this time, because the Writer uses the buffer, when the close() method is used, it will actually In case of forced buffer refresh, the content will be output at this time. If it is not closed, the output operation cannot be performed. Therefore, if you want to output all the content without closing, you can use the flush() method to force clear.  

Example: use Writer and force clear

 1 import java.io.File;
 2 import java.io.FileWriter;
 3 import java.io.Writer;
 4 public class JavaAPIDemo {
 5     public static void main(String[] args) throws Exception {
 6         File file = new File("D:" + File.separator + "hello" + File.separator + "mldn.txt");
 7         if (!file.getParentFile().exists()) {
 8             file.getParentFile().mkdirs(); // Parent directory must exist
 9         }
10         Writer out = new FileWriter(file) ; 
11         String str = "www.mldn.cn" ;
12         out.write(str); 
13         out.flush();  // Mandatory refresh
14     }
15 }
JavaAPIDemo

 

Question: can you change the code to make the difference between out.flush() and non-existent? See what's the difference between the two?

Note: the out stream in the above example cannot be closed, otherwise it will automatically flush() and it will not achieve the desired result

Byte streams do not use buffers when they are processed, but character streams use buffers. In addition, the character stream using buffer is more suitable for Chinese data processing, so in future program development, if it involves the output containing Chinese information, it will generally use character stream processing, but on the other hand, the basic processing form of byte stream and character stream is similar, because IO is used for data transmission in many cases (binary) so this lecture will focus on byte stream.

Topics: Java JDK