Platinum west learning diary --- the principle and simple use of byte input and output stream

Byte is the basic unit of file transmission, and the file content is also stored in bytes. Reading data from the file to the program uses the input stream, and reading data from the program to the file uses the output stream. (take the program as the reference object)


Output stream: superclass OutStream, whose subclass FileOutStream is used for file operation
Input stream: superclass InputStream, whose subclass FileInputStream is used for file operation
Input / output byte stream principle: only one byte will be operated at a time (read or write from the file), and the final call is the local method native method
In UTF-8 coding: one Chinese is equal to three bytes, and Chinese punctuation occupies three bytes. An English character is equal to one byte, and English punctuation occupies one byte.
Encoding in Unicode: an English is equal to two bytes, and a Chinese (including traditional) is equal to two bytes. Chinese punctuation takes up two bytes and English punctuation.

I set UTF-8 and read it once in 3 bytes, as shown in the following code:

Output stream:

    //Write from program to file
    public static void out(){
        //Determine file object
        File file = new File("1.txt");
        //Create file output stream object
        try {
            OutputStream out = new FileOutputStream(file,true);//If the second parameter is not set, it means overwrite; if it is true, it means append
            String info = "Hello\r\n";

            // '\ r\n' indicates line feed or by
            //Get newline
            String line = System.getProperty("line.separator");

            out.write(info.getBytes());
            //Refresh stream
            out.flush();
            //Close flow
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

txt file:

Input stream:

//Write program from file
    public static void input(){
        //Determine file object
        File file = new File("1.txt");
        //Create file output stream object
        try {
            /**
             * Usual writing
             */
            InputStream input = new FileInputStream(file);
            //Each read byte is read according to a certain byte
            byte[] bytes = new byte[1024];
            int len;//Indicates the length of bytes read each time
            //Used to restore to a string object after reading the byte array
            StringBuilder sb = new StringBuilder();
            //Start reading --- read the data into the array and return the number of bytes read. When it is not equal to - 1, it means that the data has been read. When it is equal to - 1, it means that it has been read
            while ((len = input.read(bytes))!=-1){
                //According to the read byte array, it is converted into a string and added to StringBuilder
                sb.append(new String(bytes));//This will cause an error in byte reading after the parameter is passed in
            }

            System.out.println(sb);

            //Close flow
            input.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

The above is based on 1024 bytes as the reading unit. At this time, there will be space chaos caused by multiple reading spaces:

Why does this happen? Because a Chinese character in UTF8 encoding is 3 bytes, if 1024 bytes are read at a time (or other bytes are 4 bytes as shown in the figure below), the bytes at the later index position will not be overwritten or filled in the byte array, or the random code of one more byte will be read as shown in the figure below:

1.txt:

 

Input stream code:

Console output:

This will lead to an extra byte of garbled code, and it happens that there will be no garbled code when reading 3 bytes at a time. It is the last garbled code every time: the reason is that when StringBuilder reads the 'bytes' array, the bytes are read once for 4 bytes, and one more byte is read at one time.

The main reason is that the last append should be added to the read length. There is no need to completely use up all bytes in the byte array:

Final code:

import java.io.*;
import java.nio.charset.StandardCharsets;

public class demo_io {
    /**
     * Byte is the basic unit of file transmission, and the file content is also stored in bytes. Reading data from the file to the program uses the input stream, and reading data from the program to the file uses the output stream
     * @param args
     */
    public static void main(String[] args) {

        /**
         * Byte input / output stream
         * Output stream: the superclass OutStream uses its subclass FileOutStream for file operations
         * Input stream: the superclass InputStream uses its subclass FileInputStream to operate on files
         * Input / output byte stream principle: only one byte will be operated at a time (read or write from the file), and the final call is the local method native method
         *
         *  In UTF-8 coding: one Chinese is equal to three bytes, and Chinese punctuation occupies three bytes. An English character is equal to one byte, and English punctuation occupies one byte.
         *  Unicode Code: one English is equal to two bytes, and one Chinese (including traditional) is equal to two bytes. Chinese and English punctuation take up two bytes.
         */

//        out();
        input();
    }

    //Write from program to file
    public static void out(){
        //Determine file object
        File file = new File("1.txt");
        //Create file output stream object
        try {
            OutputStream out = new FileOutputStream(file,true);//If the second parameter is not set, it means overwrite; if it is true, it means append
            String info = "Hello\r\n";

            // '\ r\n' indicates line feed or by
            //Get newline
            String line = System.getProperty("line.separator");

            out.write(info.getBytes());
            //Refresh stream
            out.flush();
            //Close flow
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //Write program from file
    public static void input(){
        //Determine file object
        File file = new File("1.txt");
        //Create file output stream object
        try {
            /**
             * Usual writing
             */
            InputStream input = new FileInputStream(file);
            //Each read byte is read according to a certain byte
            byte[] bytes = new byte[4];
            int len;//Indicates the length of bytes read each time
            //Used to restore to a string object after reading the byte array
            StringBuilder sb = new StringBuilder();
            //Start reading --- read the data into the array and return the number of bytes read. When it is not equal to - 1, it means that the data has been read. When it is equal to - 1, it means that it has been read
            while ((len = input.read(bytes))!=-1){
                //According to the read byte array, it is converted into a string and added to StringBuilder
                sb.append(new String(bytes,0,len));//This will cause an error in byte reading after the parameter is passed in
            }

            System.out.println(sb);

            //Close flow
            input.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

Simply view the source code:

It was originally an overloaded method called. Click in again to view:

The general content is to judge whether the parameters passed in are legal (in accordance with the rules). If not, return and read them byte by byte.

Click read() to see that it is an abstract method. Click FileInputStream to see that the abstract method it implements actually calls another method:

 

Clicking open again is a local method:

So is OutStream!

Keywords: Java io

Added by pastcow on Sat, 29 Jan 2022 22:46:54 +0200