Java basics IO flow

catalogue

1, IO stream

1. Classification of IO streams:

2. Byte input stream

Construction method of FileInputStream

3. Byte buffer stream

Encryption and decoding:

4. Character stream

Classification of character stream

Character output stream

Construction method of OutputStreamWriter

Method for OutputStreamWriter to write data

The difference between flush() and close():

5. Character input stream

Construction method of InputStreamReader

6. Character buffer stream

Character buffered output stream: BufferedWriter:

Character buffered input stream: BufferedReader:

7. Special data writing method of character stream:

8. Stream of operation basic data type

2, Serialization

1, IO stream

IO stream refers to the stream used to process data transmission between devices

1. Classification of IO streams:

flow to:

The input stream reads data from the hard disk to the Java program

The output stream writes out the data and outputs the data from the Java program to the hard disk

Data type:

Byte stream

Byte input stream read data InputStream

Byte output stream write out data OutputStream

Character stream

Character input stream read data Reader

Character output stream write out data Writer

2. Byte input stream

InputStream, which is an abstract class with a subclass FileInputStream

Construction method of FileInputStream

FileInputStream(File file):  

Create a FileInputStream by opening a connection to the actual file, which is named by the file object file in the file system.

FileInputStream(String string):

Create a FileInputStream by opening a connection to the actual file, which is named by the pathname name in the file system.

There are two ways to read data from byte input stream:

Member method of FileInputStream

public int read(): read one byte of data from the input stream

The maximum number of bytes read from the input B byte array of int [. Byte]:

Code example: the first method of read() reads one byte at a time

import java.io.FileInputStream;
 
public class Demo1 {
    public static void main(String[] args) throws Exception{
//        File file = new File("f.txt");
//        FileInputStream fis = new FileInputStream(file);
//        When encapsulating a nonexistent file, an error is reported: the system cannot find the specified file.
        FileInputStream fis = new FileInputStream("d.txt");
        int i=0;
//        Read one byte at a time and return the ASCII code value
        while((i= fis.read())!=-1){
            System.out.print((char)i);//Cast type
        }
        fis.close();
    }
}

Output result: Contents in d.txt

read(byte[] b) the second method is to read one byte array at a time

import java.io.FileInputStream;
 
 
public class Demo2 {
    public static void main(String[] args) throws Exception{
        FileInputStream fis = new FileInputStream("a.txt");
        byte[] bytes = new byte[1024];
//        Define a byte array, store the bytes actually obtained in the array, and return the number of bytes actually read in the array
        int length=0;
//        Read one byte array at a time
        while ((length= fis.read(bytes))!=-1){
            System.out.println(new String(bytes, 0, length));
//            Get the bytes from 0 to the number of bytes actually read in the array, otherwise the default value in the array will also be obtained
        }
        fis.close();
    }
}

Output result: for the contents in a.txt, since the length of the byte array obtained at one time is much larger than the number of bytes of the contents stored in the file, the while loop is actually executed only once, directly storing all the contents in the file into an array, and then outputting the actually obtained data in this array.

Examples:

Requirement: copy the contents of a.txt under the current project to b.txt

Code implementation:

import java.io.FileInputStream;
import java.io.FileOutputStream;
 
/*
        Requirement: copy the contents of a.txt under the current project to b.txt
 */
public class Demo3 {
    public static void main(String[] args) throws Exception {
//        Create byte I / O stream object
        FileInputStream fis = new FileInputStream("a.txt");
        FileOutputStream fos = new FileOutputStream("b.txt");
 
        int length=0;
        byte[] bytes = new byte[1024];
        while((length=fis.read(bytes))!=-1){
            fos.write(bytes,0,length);
        }
        fos.close();
        fis.close();
    }
}

Output result: the content in b.txt is modified to the content in a.txt

3. Byte buffer stream

The speed of byte stream reading and writing one array at a time is much faster than that of reading and writing one byte at a time. This is due to the buffer effect of array. Byte buffer stream makes the reading and writing speed more efficient

Byte buffered output stream: BufferedOutputStream

Construction method:

BufferedOutputStream(OutputStream out): creates a new buffered output stream to write data to the specified underlying output stream.

Byte buffered input stream: BufferedInputStream

Construction method:

BufferedInputStream(InputStream in): create a BufferedInputStream and save its parameters. Input the stream in for later use.

Example of byte buffered output stream:

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
 
public class Bdemo1 {
    public static void main(String[] args) throws Exception{
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d.txt"));
        bos.write("big data".getBytes());
        bos.close();
    }
}

Output result:

Example of byte buffered input stream:

import java.io.BufferedInputStream;
import java.io.FileInputStream;
 
public class Bdemo2 {
    public static void main(String[] args) throws Exception{
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("d.txt"));
        byte[] bytes = new byte[1024];
        int length = 0;
        while ((length = bis.read(bytes)) != -1) {
            System.out.println(new String(bytes, 0, length));
        }
    }
}

Output result:

When the byte stream reads only one byte at a time, if the data is Chinese, symbols that we can't understand appear. This is because Chinese is composed of three bytes or two bytes. When there is only one byte, the bytes converted from Chinese characters are split for output.

A decoding and encryption method is introduced:

Encryption and decoding:

String(byte[] bytes, Charset charset)
Construct a new String and decode charset with the specified byte array. decode

  byte[] getBytes(Charset charset)
Use the given charset to encode the String into a byte sequence and store the result in a new byte array. Code

Coding: change what you can understand into what you can't understand, which is similar to encryption
            String -- byte[]

Decoding: change what you can't understand into what you can understand, which is similar to decryption
            byte[] -- String

public class StringDemo {
    public static void main(String[] args) throws Exception {
        String s = "Hello";
 
        //String -- byte[]
//        byte[] bytes1 = s.getBytes("GBK");
        System.out.println(bytes1);
//        printArray(bytes1);
 
 
        byte[] bytes2 = s.getBytes("Unicode");
        printArray(bytes2);
 
        System.out.println();
 
        //byte[] -- String
        String s1 = new String(bytes2, "Unicode");
        System.out.println(s1);
 
 
    }
 
    public static void printArray(byte[] bytes){
        for (byte b : bytes){
            System.out.print(b+",");
        }
    }
}

Output result:

4. Character stream

Classification of character stream

Character input stream: Reader

Character output stream: Writer

Convert byte stream to character stream: character stream = byte stream + encoding table

Character output stream

Writer

OutputStreamWriter: character output stream, which is a conversion stream obtained by adding byte stream and encoding table. When writing data later, it can be written according to the encoding specified by itself

Construction method of OutputStreamWriter

public OutputStreamWriter(OutputStream out):

Create an OutputStreamWriter that uses the default character encoding. According to the default encoding, characters are used as a bridge to convert the data of byte stream into character stream

public OutputStreamWriter(OutputStream out,String charsetName):

According to the specified encoding, characters are used as a bridge to convert the data of byte stream into character stream

Code example:

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
 
public class Demo4 {
    public static void main(String[] args) throws Exception{
//        Create character output stream object
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("e.txt"), "GBK");
//        If there is no file, it will be created
        osw.write("Long live China");
        osw.close();
    }
}

Output result: Contents in e.txt file

It is found that the content of the file is not the Chinese characters written in the code

Reason: the output format in the file here is UTF-8. UTF-8 takes three bytes as a Chinese character. The format used in the code is GBK. GBK takes two bytes as a Chinese character. Although the format is wrong, the actual content is written into the file. You can see the content by converting the format to GBK.

Method for OutputStreamWriter to write data

public void write(int c): write a character

public void write(char[] cbuf): write a character array

public void write(char[] cbuf,int off,int len): write a part of a character array, starting from off and having a length of len

public void write(String str): write a string

public void write(String str,int off,int len): write a part of a string, starting from off and with a length of len

Code example:

import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
 
public class Demo5 {
    public static void main(String[] args) throws Exception{
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("f.txt"));
//        Write a character
        osw.write('a');//Write a
//        Write a part of a character array
        char[] chars = new char[]{'a','b','c','d','e','f'};
        osw.write(chars);//Write abcdef
//        Write a part of a character array
        osw.write(chars,3,2);//Write def
//        Write a string
        osw.write("CHINA");//Write CHINA
//       Write part of a string
        osw.write("CHINESE",4,3);//Write ESE
 
        osw.close();
    }
}

Output result:

If close() is removed from the code before running, the data will not be written to the file

Reason: the file is actually stored in bytes on the hard disk, which needs to be manually converted.

Solution: use the refresh stream: void flush(), so that the data can be written successfully

The underlying flush() method is further described in the source code

The difference between flush() and close():

1. After calling flush(), the stream object is not closed and can continue to write data

2. After calling close(), the flow object is closed, and subsequent data cannot be written through this object

5. Character input stream

Reader

InputStreamReader: character input stream

Construction method of InputStreamReader

public InputStreamReader(InputStream in):

Read the data and convert the data of byte stream into character stream with characters as a bridge according to the default encoding

public InputStreamReader(InputStream in,String charsetName):

Read the data and convert the data of byte stream into character stream with characters as a bridge according to the specified encoding

Method for InputStreamReader to read data (member method)

public int read(): read one character

public int read(char[] cbuf): read characters into an array

Code example: the first way: read one character at a time

import java.io.FileInputStream;
import java.io.InputStreamReader;
 
public class Demo6 {
    public static void main(String[] args) throws Exception{
        InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
        int i=0;
//        Read one character at a time
        while((i= isr.read())!=-1){
            System.out.print((char)i);
        }
        isr.close();
    }
}

The second way: read one character array at a time

import java.io.FileInputStream;
import java.io.InputStreamReader;
 
public class Demo6 {
    public static void main(String[] args) throws Exception{
        InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));;
        System.out.println("========================");
//        Read one character array at a time
        int length=0;
        char[] chars = new char[1024];
        while((length= isr.read(chars))!=-1){
            System.out.println(new String(chars,0,length));
            //Use anonymous objects to convert the obtained characters to string output
        }
        isr.close();
    }
}

Output result: the content can be read in both ways

The results are the same, and the results are obtained by running respectively:

Examples:

Requirement: copy the contents of a.txt in the current project directory to c.txt in the current project directory

This is the same as the above example, but it is implemented using character input / output stream:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
 
/*
    Copy the contents of a.txt in the current project directory to c.txt in the current project directory
 */
public class Demo7 {
    public static void main(String[] args) throws Exception{
//        Create character input / output stream object
        InputStreamReader isr = new InputStreamReader(new FileInputStream("a.txt"));
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("c.txt"));
//        The second method is used here: read one character array at a time
        int length=0;
        char[] chars = new char[1024];
        while((length= isr.read(chars))!=-1){
            osw.write(chars,0,length);
            osw.flush();
        }
//        Release resources
        osw.close();
        isr.close();
    }
}

Output result:

 

Since our common operations use the local default encoding, we basically do not specify the encoding when we use it, but when we create the character conversion stream object, the name is a little long, so Java provides subclasses for us to use

Character stream = byte stream + encoding table

OutputStreamWriter = FileOutputStream + encoding table = FileWriter

InputStreamReader = FileInputStream + encoding table = FileReader

Code example: copy operation:

import java.io.FileReader;
import java.io.FileWriter;
 
public class Demo8 {
    public static void main(String[] args) throws Exception{
        FileReader fr = new FileReader("a.txt");
        FileWriter fw = new FileWriter("f.txt");
        char[] chars = new char[1024];
        int length = 0;
        while ((length=fr.read(chars))!=-1){
            fw.write(chars,0,length);
            fw.flush();
        }
    }
}

Output result: the contents of a.txt appear in f.txt

6. Character buffer stream

Character stream in order to read and write efficiently, character buffer stream is also provided

Character buffered output stream: BufferedWriter:

Write text to the character output stream and buffer characters to provide efficient writing of individual characters, arrays and strings. You can specify the buffer size, or you can accept the default size. The default value is large enough for most purposes.

BufferedWriter(Writer out) creates a buffered character output stream using an output buffer of the default size.

Code example:

import java.io.BufferedWriter;
import java.io.FileWriter;
 
public class Bdemo3 {
    public static void main(String[] args) throws Exception {
//        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("a2.txt")));
        BufferedWriter bw = new BufferedWriter(new FileWriter("a2.txt"));
 
        bw.write("hello");
        bw.write("\r\n");
        bw.write("world");
        bw.write("\r\n");
        bw.write("java");
        bw.write("\r\n");
        bw.write("hadoop");
 
        bw.flush();
 
        //Release resources
        bw.close();
 
    }
}

Output result:

Character buffered input stream: BufferedReader:

Read text from the character input stream and buffer characters to provide efficient reading of characters, arrays and lines. You can specify the buffer size, or you can use the default size. The default value is large enough for most purposes

BufferedReader(Reader in) creates a buffered character input stream using a default size input buffer.

Code example:

import java.io.BufferedReader;
import java.io.FileReader;
 
public class Bdemo4 {
    public static void main(String[] args) throws Exception {
//        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("a2.txt")));
        BufferedReader br = new BufferedReader(new FileReader("a2.txt"));
        //1. Read one character at a time
//        int ch = 0;
//        while ((ch=br.read())!=-1){
//            System.out.print((char) ch);
//        }
 
        //2. Read one character array at a time
        char[] chars = new char[1024];
        int length = 0;
        while ((length=br.read(chars))!=-1){
            System.out.println(new String(chars,0,length));
        }
        //Release resources
        br.close();
    }
}

Output result:

The same is true for copying pictures to files:

Code example:

import java.io.FileInputStream;
import java.io.FileOutputStream;
 
public class Cdemo5 {
    public static void main(String[] args) throws Exception{
        FileInputStream br = new FileInputStream("Dora A dream.jpg");
        FileOutputStream bw = new FileOutputStream("D:\\IdeaProjects\\dlam.jpg");
 
        int length=0;
        byte[] chars = new byte[1024];
        while((length=br.read(chars))!=-1){
            bw.write(chars,0,length);
        }
        bw.close();
        br.close();
    }
}

Output result:

A jpg file is generated under this project:

7. Special data writing method of character stream:

BufferedWriter:

void newLine() writes a line separator. The line separator string is determined by the system property line Separator definition, not necessarily a single line break ('\ n') character.

BufferedReader:

public String readLine() reads a line of text. A line is treated as a line feed ('\ n') and terminated by any one of the carriage return ('\ r') or subsequent line feeds.

Code example: no exceptions will be thrown here. Use the standard writing method in development:

import java.io.*;
 
public class Bdemo5 {
    public static void main(String[] args) {
        try {
            write();
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        try {
            read();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void write() throws Exception {
        BufferedWriter bw = new BufferedWriter(new FileWriter("f.txt"));
        for(int i=1;i<=10;i++){
            bw.write("big data"+i);
            bw.newLine();
        }
        bw.close();
    }
 
    public static void read() throws Exception {
        BufferedReader br = new BufferedReader(new FileReader("f.txt"));
//        public String readLine() reads one line of text at a time
        //The string containing the contents of the line, excluding any line termination characters. It is null if it has reached the end of the stream
        String line=null;
        while((line=br.readLine())!=null){
            System.out.println(line);
        }
        br.close();
    }
}

Output result: f.txt contains the data read as follows:

8. Stream of operation basic data type

DataOutputStream

DataInputStream

Code example: write data

import java.io.DataOutputStream;
import java.io.FileOutputStream;
 
public class Demo1 {
    public static void main(String[] args) throws Exception{
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("d.txt"));
        dos.writeByte(1);
        dos.writeShort(5);
        dos.writeInt(10);
        dos.writeLong(1000L);
        dos.writeChar('a');
        dos.writeFloat(12.34F);
        dos.writeDouble(34.56);
        dos.writeBoolean(true);
        dos.close();
    }
}

Output result: in the d.txt file, the content is garbled

But the content has been written to d.txt.

Read data of basic data type:

Note: here, it is necessary to ensure that the data type of written data is consistent with the data type order of read data.

 

import java.io.DataInputStream;
import java.io.FileInputStream;
 
public class Demo1a {
    public static void main(String[] args) throws Exception {
        DataInputStream dis = new DataInputStream(new FileInputStream("d.txt"));
        System.out.println(dis.readByte());
        System.out.println(dis.readShort());
        System.out.println(dis.readInt());
        System.out.println(dis.readLong());
        System.out.println(dis.readChar());
        System.out.println(dis.readFloat());
        System.out.println(dis.readDouble());
        System.out.println(dis.readBoolean());
 
        dis.close();
    }
}

Output result:

2, Serialization

Serialization: storing objects in a text file or database in the same way as a stream or transmitting them on the network

Object -- stream data: ObjectOutputStream

Deserialization: restore the stream object data in the text file or the stream data in the network to an object

Stream data --- object: ObjectInputStream

Code example:

Person class:

public class Person {
    private String name;
    private int age;
 
    public Person() {
    }
 
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Test class:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
 
public class Demo1b {
    public static void main(String[] args) {
//        Write method: storing objects into files is actually to persist the objects
        try {
            write();
        } catch (Exception e) {
            e.printStackTrace();
        }
//        Read method: restore the stream object data in the text file or the stream data in the network to an object
//
        try {
            read();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void write() throws Exception{
//        Create object output stream object
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("g.txt"));
        Person person = new Person("superman",20);
        oos.writeObject(person);
        oos.close();
    }
    public static void read() throws Exception{
//        Create object input stream object
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("g.txt"));
        Object o = ois.readObject();
        System.out.println(o);
        ois.close();
    }
}

An error will appear here: NotSerializableException is not a serialized exception

Explanation: the serialization of classes is implemented by Java io. The class of the serializable interface is enabled. Classes that do not implement this interface will not serialize or deserialize any state. All subtypes of a serializable class are serializable.
The serialization interface has no methods or fields and is only used to identify Serializable semantics. Therefore, you need to implement the Serializable interface

You don't have to rewrite any methods.

Person class after interface implementation:

 

import java.io.Serializable;
 
public class Person implements Serializable {
    private String name;
     int age;
 
    public Person() {
    }
 
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Results after running again:

However, if the permission modifier of age in the Person class is removed and changed, and then the data reading method is run separately, an error will be reported: InvalidClassException

Explanation: Serializable here represents a tag, which is equivalent to a tag value. If the tag value given at the beginning is 100, the tag values of write data and read data are 100. After writing data and reading data, modify the Person class. At this time, a new tag value 200 will be generated for the changed Person class. When using this tag to read data, The Person tag is 200, but the tags for writing and reading data have not been modified and are still 100, so the tag cannot be found, so an error is reported.

terms of settlement:

There is a method that will not affect the tag value when modifying the class. Java provides an ID value: serialVersionUID

At the same time, if you don't want a value stored in the file, Java provides a keyword so that we can choose which members are not serialized in the serialization process: transient

Final code:

import java.io.Serializable;
 
public class Person implements Serializable {
    private static final long serialVersionUID = -1408968761740608781L;
    private String name;
    private transient int age;
 
    public Person() {
    }
 
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        this.age = age;
    }
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Output result:

The age changes to the default value of 0

Keywords: Java Back-end

Added by adroit on Sun, 20 Feb 2022 05:26:25 +0200