Summary of java I/O system

Summary of java I/O system

Summary of java I/O system

Understanding of I/O flow

First look at the concept of flow

A stream is a sequence of bytes with a starting point and an ending point. It is a general term or abstraction for data transmission. That is, the transmission of data between two devices is called a stream. The essence of a stream is data transmission. According to the characteristics of data transmission, the stream is abstracted into various types to facilitate more intuitive data operations.

In layman's terms, there are two files A and B. If you want to copy the content of A to B, you can assume that there is a channel between the two files to transfer the data of A to B in the form of bytes or characters. This channel is the concept of java I/O system flow, that is, the flow can be regarded as an abstract channel.

Understand the concept of flow, and the classification of flow will be easy to understand. In terms of the flow direction, the flow is read from the outside (network or disk) to the program (memory), which is the input flow. The flow from the program to the outside world is the output flow.

Basic flow

Streams can be divided into byte streams and character streams according to the type of data to be transmitted. The simple understanding is whether the transmission is binary bytes (byte stream) or directly understandable characters (character stream). Combining input and output streams, the basic classes (interfaces) of java I/O streams mainly include the following:

  1. InputStream (input byte stream)
  2. OutputStream (output byte stream)
  3. Reader (input character stream)
  4. Writer (output character stream)

About byte stream

The byte stream is the most basic I/O processing stream. The reason is that all forms of storage (file, disk or network) are stored in the form of bytes at the bottom. InputStream is the parent class of all byte input streams, and OutputStream is the parent class of all byte output streams. The byte stream is mainly used to process binary data. The processing unit is mainly bytes or byte arrays.

About character streams

In view of the fact that some files are stored in text, for the convenience of operation, there is a character stream. The character stream is mainly used to process characters or strings. Each character occupies two bytes. In terms of implementation, the character stream is formed by converting bytes into characters (every 2 bytes into a character) by the java virtual machine. The parent class of the character input stream is Writer, and the parent class of the character output stream is Reader.

Example

Other streams are based on the expansion and implementation of the above 4 basic interfaces. Take file transfer as an example, if the transfer type is byte, there are FileInputStream (file input stream) and FileOutputStream (file output stream). Take a look at the example:


  /**
     *  
     *  
     *  hello.txt "hello,world"
     */
    @Test
    public void testInputStream() throws Exception {
        InputStream inputStream = null;
        try {
           //
            File file = new File("/Users/wangtonghe/local/tmp/hello.txt");
           // 
            inputStream = new FileInputStream(file);
            int b = 0;
           // 
            while ((b = inputStream.read()) != -1) {
               // 
                System.out.println((b);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }


 

The above example is very simple, that is, the file to be operated is packed into the file input stream and read into the memory.

Look at an overall example, the input and output of character type files. Copy the content of a.txt to b.txt. FileWriter represents the file character output class, and FileReader represents the file character input class.

The general approach is to pack a.txt into a file input stream and read it into memory. Then output to the b.txt file through the file output stream.

Use the chart to describe it as


    @Test
    public void testFile() throws Exception {

        File aFile = new File("/Users/wangtonghe/local/tmp/a.txt");
        File bFile = new File("/Users/wangtonghe/local/tmp/b.txt");

        FileReader reader = null;
        FileWriter writer = null;

        try {
           // 
            reader = new FileReader(aFile);
           // 
            writer = new FileWriter(bFile);
            char[] chars = new char[1024];
            int len = 0;
           // 
            if ((len = reader.read(chars)) != -1) {
               //
                writer.write(chars, 0, len);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                reader.close();
            }
            if (writer != null) {
                writer.close();
            }
        }
    }

 

The difference between byte stream and character stream

  1. The operation object is different, this is the most basic difference. The byte stream manipulates bytes or byte arrays; the character stream manipulates characters or strings.
  2. The byte stream directly operates on the terminal (file, etc.), while the character stream uses a buffer (that is, the data is written to the buffer area first, and then the buffer area is operated)
  3. Due to the existence of 2, the operation on the byte will directly affect the terminal (file) result, and the operation on the character stream must close the stream or forcibly refresh the stream to write the data, otherwise it will only be written to the buffer area, and the file and other terminals will not be affected. influences.
  4. See the difference between java byte stream and character stream for details

The mutual transformation of the two streams

InputStreamReader and OutputStreamWriter are responsible for the conversion between the two streams. (Usually it is byte stream to character stream, there is no character to byte, and it is not needed)

InputStreamReader can convert byte input stream into character input stream; OutputStreamWriter can convert byte output stream into character output stream.

The conversion process is as follows:


//
 File aFile = new File("/Users/wangtonghe/local/tmp/a.txt");
// 
 FileInputStream fileInputStream = new FileInputStream(aFile);
// 
 Reader reader = new InputStreamReader(fileInputStream);

 

The conversion flow construction method and usage are as follows

  1. InputStreamReader(InputStream);//Initialized by the constructor, using the system default encoding table GBK.
  2. InputStreamWriter(InputStream,String charSet);//Initialized by this constructor, you can specify the encoding table.
  3. OutputStreamWriter(OutputStream);//Initialized by this constructor, using the system default encoding table GBK.
  4. OutputStreamwriter(OutputStream,String charSet);//Initialized by the constructor, you can specify the encoding table

I/O flow overview

The general class and structure of the java system I/O flow is shown in the figure above.

Briefly introduce

Input byte stream InputStream

  1. InputStream is the parent class of all input byte streams, and it is an abstract class.
  2. ByteArrayInputStream, StringBufferInputStream, and FileInputStream are three basic media streams, which read data from Byte array, StringBuffer, and local files respectively.
  3. ObjectInputStream and all FilterInputStream subclasses are decorated streams (the protagonist of the decorator pattern).

Similarly, the output byte stream OutputStream is similar to this

  1. OutputStream is the parent class of all output byte streams, and it is an abstract class.
  2. ByteArrayOutputStream and FileOutputStream are two basic media streams, which write data to Byte array and local file respectively.
  3. ObjectOutputStream and all subclasses of FilterOutputStream are decorative streams.

Decorator pattern of I/O system

Regarding the I/O system, what must be discussed is the design pattern of its decorator.

Decorator mode

Concept Decorator Pattern allows adding new functionality to an existing object without changing its structure. It allows us to keep the system more flexible when extending classes.

I won t specifically introduce the decorator pattern here, you can look at Java Design Pattern 12: Decorator Pattern

The decorator pattern in java I/O is mainly implemented by FilterInputStream and its subclasses (input stream) and FilterOutputStream and its subclasses.

For example, BufferedInputStream, an input stream with buffering function, can modify FileIntputStream to have buffering function.

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("/home/user/abc.txt")));

Reference article

  1. The difference between java byte stream and character stream
  2. Detailed explanation of the difference between byte stream and character stream
  3. Java IO stream learning summary one: input and output streams
  4. Java Design Pattern 12: Decorator Pattern
  5. Java IO: Stream, and the use of the decorator pattern on it