Foreword
io stream uses a lot of places, such as uploading and downloading, transmission, design mode, etc.. The foundation is solid, in order to play higher-end.

The best programmers who believe that the IO stream is really understood by the blogger will analyze the following four points each time before using the IO stream:

(1) Defining whether the data to be operated is the data source or the data purpose (that is, whether to read or write)
(2) Determining whether the data on the device to be operated is byte or text
(3) Defining the specific device where the data is located
(4) ) Determine if additional functionality is needed (such as whether you need to convert streams, efficient streams, etc.)

The above four points will be summarized in the four points of the article confession IO flow. If you are really skilled at the above four points, I don’t think you have to read this article because you have already played IO in the palm of your hand. Everything can be used by you and you can stop talking.

@

1. Four points of confession IO flow

(1) Determining whether the data to be operated is the data source or the purpose of the data (to read or write)

Source: InputStream Reader

Purpose: OutputStream Writer

(2) Determining whether the data on the device to be operated is a byte or a text

source:

Byte: InputStream

Text: Reader

purpose:

Byte: OutputStream

Text: Writer

(3) Identify the specific equipment where the data is located

Source device:

Hard Drive: Files Filebeginning

Memory: array, string

keyboard:System.in

The internet:Socket

Corresponding destination equipment:

Hard Drive: Files Filebeginning

Memory: array, string

screen:System.out

The internet:Socket

(4) Determining if additional features are needed

Need to convert – convert stream InputStreamReader, OutputStreamWriter

Need to be efficient – buffer stream Bufferedxxx

Multiple sources – sequence stream SequenceInputStream

Object serialization – ObjectInputStream, ObjectOutputStream

Guaranteed data output form – print stream PrintStream, Printwriter

Manipulate basic data, guarantee byte integrity – DataOutputStream, DataInputStream

Here, let’s take a look at the IO stream classification,
IO_stream_operations_complete_of_Java_0.png

OK, ready to confess IO flow?

2, File class

As for the IO stream, that is, the input and output streams, starting from the file to the end of the file, the files are inseparable from beginning to end, so the IO stream has to start from the file File class.

1.1 File Overview

java.io.FileA class is a class that operates on a file. It can only operate on the file itself, and cannot manipulate the contents of the file.
java.io.FileA class is an abstract representation of file and directory path names. It is mainly used for operations such as creating, finding, and deleting files and directories.

How to understand the above two sentences? it’s actually really easy!

The first sentence is that File is not related to streaming, File class can not read and write files, that is, input and output!
That second sentence File mainly expressed similar D:\\文件目录1to D:\\文件目录1\\文件.txt, the former is a folder (Directory) while the latter is a file (file), and the File class is operating both categories.

1.2 Construction method

In Java, everything is an object, and the File class is no exception. No matter which object should be said from the construction of the object, the blogger analyzes Filethe constructor of the analysis class. Start with the API.
IO_stream_operations_complete_of_Java_1.png

Let’s take a look at the three more commonly used ones:

1. Create a new File instance by converting the public File(String pathname)given pathname string to an abstract pathname.
2. Create a new File instance public File(String parent, String child)from the parent pathname string and the subpathname string .
3. Create a new File instance public File(File parent, String child)from the parent abstract pathname and subpathname string .

Seeing the word description is not vivid enough, the image is not strong enough? Nothing to do, the following example of construction, immediately vivid, the code is as follows:

1. 一个File对象代表硬盘中实际存在的一个文件或者目录。
2.  File类构造方法不会给你检验这个文件或文件夹是否真实存在,因此无论该路径下是否存在文件或者目录,都不影响File对象的创建。
// 文件路径名 
String path = "D:\\123.txt";
File file1 = new File(path); 

// 文件路径名
String path2 = "D:\\1\\2.txt";
File file2 = new File(path2);     -------------相当于D:\\1\\2.txt

// 通过父路径和子路径字符串
 String parent = "F:\\aaa";
 String child = "bbb.txt";
 File file3 = new File(parent, child);  --------相当于F:\\aaa\\bbb.txt

// 通过父级File对象和子路径字符串
File parentDir = new File("F:\\aaa");
String child = "bbb.txt";
File file4 = new File(parentDir, child); --------相当于F:\\aaa\\bbb.txt

Note on the File class:

  1. A File object represents a file or directory that actually exists on the hard disk.
  2. The File class constructor won’t let you verify that the file or folder actually exists, so whether or not files or directories exist under the path does not affect the creation of the File object.

1.3 Common methods

Common methods of File are mainly divided into acquisition function, obtaining absolute path and relative path, judging function, and creating delete function.

1.3.1 How to get the function

1, public String getAbsolutePath(): Returns the absolute path name string of this File.

2. public String getPath(): Convert this File to a path name string.

3. public String getName()Return the name of the file or directory represented by this File.

4. public long length()Return the length of the file represented by this File.

The above method test, the code is as follows [note that the test is based on your own computer folder]:

public class FileGet {
    public static void main(String[] args) {
        File f = new File("d:/aaa/bbb.java");     
        System.out.println("文件绝对路径:"+f.getAbsolutePath());
        System.out.println("文件构造路径:"+f.getPath());
        System.out.println("文件名称:"+f.getName());
        System.out.println("文件长度:"+f.length()+"字节");

        File f2 = new File("d:/aaa");     
        System.out.println("目录绝对路径:"+f2.getAbsolutePath());
        System.out.println("目录构造路径:"+f2.getPath());
        System.out.println("目录名称:"+f2.getName());
        System.out.println("目录长度:"+f2.length());
    }
}
输出结果:
文件绝对路径:d:\aaa\bbb.java
文件构造路径:d:\aaa\bbb.java
文件名称:bbb.java
文件长度:2116字节

目录绝对路径:d:\aaa
目录构造路径:d:\aaa
目录名称:aaa
目录长度:3236

Note: length(), indicates the length of the file. However File, if the object represents a directory, the return value is not specified.

1.3.2 Absolute and relative paths

Absolute path : A complete path that begins with a drive letter, for example F://aaa.txt.
Relative path : A simplified path that does not begin with a drive letter, for example //aaa.txt//b.txt.

1, the path is not case sensitive
2, the file name separator in the path windows use backslashes, backslashes are escape characters, and two backslashes represent a normal backslash

//绝对路径
public class FilePath {
    public static void main(String[] args) {
        // D盘下的bbb.java文件
        File f = new File("D:\\bbb.java");
        System.out.println(f.getAbsolutePath());
        
        // 项目下的bbb.java文件
        File f2 = new File("bbb.java");
        System.out.println(f2.getAbsolutePath());
    }
}
输出结果:
D:\bbb.java
D:\java\bbb.java

1.3.3 Method of judging function

1, public boolean exists(): Whether the file or directory represented by this File actually exists.
2 public boolean isDirectory(): Whether this File indicates a directory.
3. public boolean isFile(): Whether this file indicates a file.

Method demonstration, the code is as follows:

public class FileIs {
    public static void main(String[] args) {
        File f = new File("d:\\aaa\\bbb.java");
        File f2 = new File("d:\\aaa");
        // 判断是否存在
        System.out.println("d:\\aaa\\bbb.java 是否存在:"+f.exists());
        System.out.println("d:\\aaa 是否存在:"+f2.exists());
        // 判断是文件还是目录
        System.out.println("d:\\aaa 文件?:"+f2.isFile());
        System.out.println("d:\\aaa 目录?:"+f2.isDirectory());
    }
}
输出结果:
d:\aaa\bbb.java 是否存在:true
d:\aaa 是否存在:true
d:\aaa 文件?:false
d:\aaa 目录?:true

1.3.4 How to Create a Delete Function

  • public boolean createNewFile(): The file does not exist, create a new empty file and return true, the file exists, does not create the file and returns false.
  • public boolean delete() : Delete the file or directory represented by this File.
  • public boolean mkdir() : Create a directory represented by this File.
  • public boolean mkdirs() : Create a directory represented by this File, including any parent directories that are required but not present.

Among them, mkdirs()and mkdir()the method is similar, but mkdir()only to create a directory, mkdirs()you can create multi-level directory for example //a//b//c, the development in general usemkdirs() ;

Of note in these methods is the createNewFile method and the difference between mkdir and mkdirs .

Method test, the code is as follows:

public class FileCreateDelete {
    public static void main(String[] args) throws IOException {
        // 文件的创建
        File f = new File("aaa.txt");
        System.out.println("是否存在:"+f.exists()); // false
        System.out.println("是否创建:"+f.createNewFile()); // true
        System.out.println("是否创建:"+f.createNewFile()); // 以及创建过了所以再使用createNewFile返回false
        System.out.println("是否存在:"+f.exists()); // true
        
        // 目录的创建
        File f2= new File("newDir");    
        System.out.println("是否存在:"+f2.exists());// false
        System.out.println("是否创建:"+f2.mkdir()); // true
        System.out.println("是否存在:"+f2.exists());// true

        // 创建多级目录
        File f3= new File("newDira\\newDirb");
        System.out.println(f3.mkdir());// false
        File f4= new File("newDira\\newDirb");
        System.out.println(f4.mkdirs());// true
      
        // 文件的删除
        System.out.println(f.delete());// true
      
        // 目录的删除
        System.out.println(f2.delete());// true
        System.out.println(f4.delete());// false
    }
}

Note: deleteMethod, if this Filerepresents a directory, the directory must be empty to be deleted.

1.4 traversal of the directory

  • public String[] list() : Returns a String array representing all the subfiles or directories in the File directory.
  • public File[] listFiles() : Returns a File array representing all the subfiles or directories in the File directory.
public class FileFor {
    public static void main(String[] args) {
        File dir = new File("G:\光标");
      
        //获取当前目录下的文件以及文件夹的名称。
        String[] names = dir.list();
        for(String name : names){
            System.out.println(name);
        }
        //获取当前目录下的文件以及文件夹对象,只要拿到了文件对象,那么就可以获取更多信息
        File[] files = dir.listFiles();
        for (File file : files) {
            System.out.println(file);
        }
    }
}

IO_stream_operations_complete_of_Java_2.png

listFiles must satisfy the following two conditions when obtaining a file or folder in the specified directory.

1, the specified directory must exist

2, the specified must be a directory. Otherwise it is easy to cause the return array to be null, and a NullPointerException will occur.

1.5 Recursively traverse all files and subfiles under the folder

Don’t say anything, just go directly to the code:

package File;

import java.io.File;

//递归遍历文件夹下所有的文件
public class RecursionDirectory {
    public static void main(String[] args) {
      File file=new File("D:\\java专属IO测试");
        Recursion(file);
    }
    public static void Recursion(File file){
        //1、判断传入的是否是目录
        if(!file.isDirectory()){
            //不是目录直接退出
            return;
        }
        //已经确保了传入的file是目录
        File[] files = file.listFiles();
        //遍历files
        for (File f: files) {
            //如果该目录下文件还是个文件夹就再进行递归遍历其子目录
            if(f.isDirectory()){
                //递归
                Recursion(f);
            }else {
                //如果该目录下文件是个文件,则打印对应的名字
                System.out.println(f.getName());
            }

        }
    }
}

If you have any questions about the above code, feel free to contact me, the blogger is always there!

3, preliminary IO flow

1.1 What is IO?

I think everyone here has definitely experienced such a scene. When you edit a text file, you can use eclipse to play the code. Forgot ctrl+s, at the moment you close the file, you have a button that you shouldn’t have, but you reacted, and the heart has already been pulled out.

We can regard the transmission of such data as a kind of data flow. According to the direction of flow, based on memory, it is divided into 输入inputand 输出output, that is, the flow of output to the memory is the input stream and the output stream flowing out of the memory.

The I/O operation in Java mainly refers to the use java.ioof the contents of the package for input and output operations. Input is also called read data, and output is also called write data .

1.2 Classification of IO

The flow of data is divided into: the input stream and output stream .

  • Input stream : A stream from 其他设备which data is read to 内存.
  • Output stream : A stream from 内存which data is written to 其他设备.

Depending on the type of data is divided into: byte stream and character stream .

  • Byte stream : A stream of data that is read and written in bytes.
  • Character stream : A stream of data that is read and written in characters.

Corresponding superclass after classification (V8 hint: superclass is also the meaning of parent class)
| | Input stream | Output stream
|–|–|–|
| Byte stream | Byte input stream InputStream | Byte output Stream OutputStream |
| Character Stream | Character Input Stream Reader | Character Output Stream Writer |

Note :
The subclass names of these four classes are basically suffixes with their parent class names as subclass names .
Such as: Subclass FileInputStream of InputStream.
Such as: Reader subclass FileReader.
IO_stream_operations_complete_of_Java_3.png

1.3 About IO’s diversion instructions

I don’t even say it, look at the picture.
IO_stream_operations_complete_of_Java_4.png

IO_stream_operations_complete_of_Java_5.png

The story of the byte stream OutputStream and InputStream

Inherited relationship between OutputStream and InputStream
IO_stream_operations_complete_of_Java_6.png

2.1 Everything in the world of files is bytes

What we have to make clear is that all file data (text, images, video, etc.) is stored as binary digits when stored, all in one byte, so the same is true for transmission. Therefore, the byte stream can transfer arbitrary file data. In the operation of the flow, we must always be clear, no matter what kind of stream object is used, the underlying transmission is always binary data.

2.2 byte output stream (OutputStream)

java.io.OutputStreamAn abstract class is a superclass (parent) that represents all the classes of a byte output stream , writing out the specified byte information to the destination. It defines the basic common function method of the byte output stream. Don’t ask me why you can define the basic common function method of the byte output stream. Bear dei, the last sentence says that OutputStream is the super-class of all output of the byte output stream. Class ,
inherit

knowledge, understand? (If that is true of white students do not understand, you can click on the blue font
inherited

into the tutorial)OutputStream

 

 

The basic common function method of the byte output stream :

1. public void close()Close this output stream and release any system resources associated with this stream.
2 public void flush().: Refresh this output stream and force any buffered output bytes to be written out.
3. public void write(byte[] b)Write b.length bytes from the specified byte array to this output stream.
4. public void write(byte[] b, int off, int len)Write len bytes from the specified byte array and output to the output stream starting from the offset off. That is to say, starting from the number of off bytes until the end of len bytes is
5 public abstract void write(int b): The specified byte is outputted.

The above five methods are methods that the byte output stream has, which is provided by the parent class OutputStream definition, and the subclass will share the above method.

FileOutputStream class

OutputStreamThere are many subclasses, we start with the simplest subclass of FileOutputStream. Look at the name to know the file output stream, used to write data out to the file.

FileOutputStream constructor

Regardless of the scorpion, only the object, start with the constructor!

1, public FileOutputStream(File file): Create an object based on the File object as a parameter.
2 public FileOutputStream(String name).: Create an object based on the name string as a parameter.

Recommend the second construction method [developed commonly used]:

FileOutputStream outputStream = new FileOutputStream("abc.txt");

In the above code, there are three things to do to create a byte output stream object like this :
1. Call the system function to create a file [output stream object will be created automatically]
2. Create outputStream object
3, put foutputStream Object points to this file

Note :
When creating an output stream object, the system will automatically create a corresponding file for the corresponding location. When the output stream object is created, the FileNotFoundException will be reported if the file does not exist, that is, the system cannot find the specified file exception.

When you create a stream object, you must pass in a file path directly or indirectly. For example, now we create a FileOutputStreamstream object, under which it will be created without this file. If there is this file, the data of this file will be cleared. Interested children’s shoes can be tested, the specific code is as follows:

public class FileOutputStreamConstructor throws IOException {
    public static void main(String[] args) {
        // 使用File对象创建流对象
        File file = new File("G:\\自动创建的文件夹\\a.txt");
        FileOutputStream fos = new FileOutputStream(file);
      
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("G:\\b.txt");
    }
}

FileOutputStream writes out byte data

Using FileOutputStream to write out byte data mainly through the Writemethod, and the writemethod is divided into the following three

public void write(int b)
public void write(byte[] b)
public void write(byte[] b,int off,int len)  //从`off`索引开始,`len`个字节
  1. Write the byte : write(int b)method, each time you can write a byte of data, the code is as follows:
public class IoWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("fos.txt");     
        // 写出数据
        fos.write(97); // 写出第1个字节
        fos.write(98); // 写出第2个字节
        fos.write(99); // 写出第3个字节
        // 关闭资源
        fos.close();
    }
}
输出结果:
abc
  1. Although the parameter is four bytes of int type, only one byte of information is written out.
  2. After the stream operation is completed, you must release the system resources and call the close method. Remember.
  1. Write out the byte array : write(byte[] b), each time you can write out the data in the array, the code uses the demo:
public class FOSWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("fos.txt");     
        // 字符串转换为字节数组
        byte[] b = "麻麻我想吃烤山药".getBytes();
        // 写出字节数组数据
        fos.write(b);
        // 关闭资源
        fos.close();
    }
}
输出结果:
麻麻我想吃烤山药
  1. Write the specified length byte array : write(byte[] b, int off, int len), each time you write out the offindex, the lenbytes, the code is as follows:
public class FOSWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("fos.txt");     
        // 字符串转换为字节数组
        byte[] b = "abcde".getBytes();
        // 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
        fos.write(b,2,2);
        // 关闭资源
        fos.close();
    }
}
输出结果:
cd

FileOutputStream implements data addition and writing, line wrapping

After the above code test, each time the program runs, each time the output stream object is created, the data in the target file is cleared. How can I keep the data in the target file and continue to append new data ? And to achieve a new line ? In fact, it is very simple. At this time, we have to learn FileOutputStreamanother two construction methods, as follows:

1,public FileOutputStream(File file, boolean append)

2,public FileOutputStream(String name, boolean append)

In the two constructors, the second parameter needs to pass a value of type boolean, trueindicating that the data falseis appended , indicating that the data is not appended or the original data is cleared. The output stream object created in this way can specify whether to add the continuation, as for the Windows line feed \n\r, which will be described in detail below.

The data addition code is implemented as follows:

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("fos.txt",true);     
        // 字符串转换为字节数组
        byte[] b = "abcde".getBytes();
        // 写出从索引2开始,2个字节。索引2是c,两个字节,也就是cd。
        fos.write(b);
        // 关闭资源
        fos.close();
    }
}
文件操作前:cd
文件操作后:cdabcde

In the Windows system, the newline symbol is \r\n, the specific code is as follows:

public class FOSWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileOutputStream fos = new FileOutputStream("fos.txt");  
        // 定义字节数组
        byte[] words = {97,98,99,100,101};
        // 遍历数组
        for (int i = 0; i < words.length; i++) {
            // 写出一个字节
            fos.write(words[i]);
            // 写出一个换行, 换行符号转成数组写出
            fos.write("\r\n".getBytes());
        }
        // 关闭资源
        fos.close();
    }
}

输出结果:
a
b
c
d
e
  • Carriage return \rand line feed \n:
    • Carriage return: Go back to the beginning of a line (return).
    • Newline: The next line (newline).
  • Line breaks in the system:
    • In Windows, the end of each line is 回车+换行, ie \r\n;
    • In Unix systems, each line ends only 换行, that is \n;
    • In the Mac system, the end of each line is 回车, ie \r. Start with Linux from Mac OS X.

2.3 byte input stream (InputStream)

java.io.InputStreamAn abstract class is a superclass (parent) that represents all the classes of a byte input stream , and can read byte information into memory. It defines the basic commonality of the byte input stream.

Basic common function methods for byte input streams :

1. public void close()Close this input stream and release any system resources associated with this stream.
2. public abstract int read(): Read the next byte of data from the input stream.

3, public int read(byte[] b): The int value returned by this method represents how many bytes are read, and a few are read back, and no return is read -1

FileInputStream class

java.io.FileInputStreamA class is a file input stream that reads bytes from a file.

Constructor for FileInputStream

1. FileInputStream(File file)Create a FileInputStream by opening the connection to the actual file, which is named by the File object file in the file system.
2. FileInputStream(String name)Create a FileInputStream by opening a connection to the actual file named by the pathname name in the file system.

Similarly, the second constructor is recommended :

 FileInputStream inputStream = new FileInputStream("a.txt");

When you create a stream object, you must pass in a file path. Under this path, if there is no such file, it will be thrown FileNotFoundException.

Construction example, the code is as follows:

public class FileInputStreamConstructor throws IOException{
    public static void main(String[] args) {
        // 使用File对象创建流对象
        File file = new File("a.txt");
        FileInputStream fos = new FileInputStream(file);
      
        // 使用文件名称创建流对象
        FileInputStream fos = new FileInputStream("b.txt");
    }
}

FileInputStream reads byte data

  1. Read byte : readmethod, each time you can read one byte of data, promoted to int type, read to the end of the file, return -1, the code test is as follows [read.txt file content is abcde]:
public class FISRead {
    public static void main(String[] args) throws IOException{
        // 使用文件名称创建流对象
        FileInputStream fis = new FileInputStream("read.txt");//read.txt文件中内容为abcde
        // 读取数据,返回一个字节
        int read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        read = fis.read();
        System.out.println((char) read);
        // 读取到末尾,返回-1
        read = fis.read();
        System.out.println( read);
        // 关闭资源
        fis.close();
    }
}
输出结果:
a
b
c
d
e
-1

Loop improved read mode, code usage demo:

public class FISRead {
    public static void main(String[] args) throws IOException{
        // 使用文件名称创建流对象
        FileInputStream fis = new FileInputStream("read.txt");
        // 定义变量,保存数据
        int b ;
        // 循环读取
        while ((b = fis.read())!=-1) {
            System.out.println((char)b);
        }
        // 关闭资源
        fis.close();
    }
}
输出结果:
a
b
c
d
e
  1. Use the byte array to read : read(byte[] b), each time read the length of b bytes into the array, return the number of valid bytes read, return to the end, return -1, the code uses the demo:
public class FISRead {
    public static void main(String[] args) throws IOException{
        // 使用文件名称创建流对象.
        FileInputStream fis = new FileInputStream("read.txt"); // read.txt文件中内容为abcde
        // 定义变量,作为有效个数
        int len ;
        // 定义字节数组,作为装字节数据的容器   
        byte[] b = new byte[2];
        // 循环读取
        while (( len= fis.read(b))!=-1) {
            // 每次读取后,把数组变成字符串打印
            System.out.println(new String(b));
        }
        // 关闭资源
        fis.close();
    }
}

输出结果:
ab
cd
ed

Because the read.txtcontent of the file is abcdewrong, the error data dis because only one byte is read eduring the last reading. In the array, the last read data is not completely replaced [note that it is replaced, see the figure below], so Pass len, get a valid byte
IO_stream_operations_complete_of_Java_7.png

code as follows:

public class FISRead {
    public static void main(String[] args) throws IOException{
        // 使用文件名称创建流对象.
        FileInputStream fis = new FileInputStream("read.txt"); // 文件中为abcde
        // 定义变量,作为有效个数
        int len ;
        // 定义字节数组,作为装字节数据的容器   
        byte[] b = new byte[2];
        // 循环读取
        while (( len= fis.read(b))!=-1) {
            // 每次读取后,把数组的有效字节部分,变成字符串打印
            System.out.println(new String(b,0,len));//  len 每次读取的有效字节个数
        }
        // 关闭资源
        fis.close();
    }
}

输出结果:
ab
cd
e

It is generally highly recommended to use an array to read files during development. The code is as follows:

package io;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class input2 {
    public static void main(String args[]){
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream("a.txt");
            int len = 0 ;
            byte[] bys = new byte[1024];
            while ((len = inputStream.read(bys)) != -1) {
                System.out.println(new String(bys,0,len));
            }
        
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

Byte stream FileInputstream copy image

Copy picture principle
IO_stream_operations_complete_of_Java_8.png

Code

Copy the image file, the code is as follows:

public class Copy {
    public static void main(String[] args) throws IOException {
        // 1.创建流对象
        // 1.1 指定数据源
        FileInputStream fis = new FileInputStream("D:\\test.jpg");
        // 1.2 指定目的地
        FileOutputStream fos = new FileOutputStream("test_copy.jpg");

        // 2.读写数据
        // 2.1 定义数组
        byte[] b = new byte[1024];
        // 2.2 定义长度
        int len;
        // 2.3 循环读取
        while ((len = fis.read(b))!=-1) {
            // 2.4 写出数据
            fos.write(b, 0 , len);
        }

        // 3.关闭资源
        fos.close();
        fis.close();
    }
}

Note : Copy text, images, mp3, video, etc. in the same way .

At this point, the byte stream OutputStream and InputStream have been talked about from the File class, and will now be mainly from the story of the character stream Reader and Writer.

Character stream Reader and Writer story

The story of the character stream Reader and Writer begins with their inheritance diagrams, and I don’t even say it.
IO_stream_operations_complete_of_Java_9.png

Character stream

The origin of the character stream: Because of the different data encoding, there is a stream object that efficiently operates on the character. The essence of the character stream is actually based on the byte stream reading, and the specified code table is checked, and the byte stream is directly read. The data will be garbled (reading Chinese will be garbled), this time Xiaobai students can’t understand, nothing, let’s look at a program first:

package IO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class CharaterStream {
    public static void main(String[] args) throws Exception {
        //FileInputStream为操作文件的字符输入流
        FileInputStream inputStream = new FileInputStream("a.txt");//内容为哥敢摸屎

        int len;
        while ((len=inputStream.read())!=-1){
           System.out.print((char)len);
        }

    }
}
运行结果:   ??¥??¢????±

Analysis of the specific situation In other
IO_stream_operations_complete_of_Java_10.png

words, your brother, I dare to touch si, then your brother, I certainly don’t know this thing:??¥??¢????±

When a byte stream reads Chinese characters, the full characters may not be displayed, because a Chinese character occupies multiple bytes of storage.

Is there no way for that byte stream? No, the byte stream still has a way, just a little trouble, the code is as follows:

public class CharaterStream {
    public static void main(String[] args) throws Exception {

        FileInputStream inputStream = new FileInputStream("a.txt");
        byte[] bytes = new byte[1024];
        int len;
        while ((len=inputStream.read(bytes))!=-1){
           System.out.print(new String(bytes,0,len));
        }
    }
}
运行结果: 哥敢摸屎

What is this? It is true that the decoding is correct String, new String()the source code is viewed , the Stringconstructor has a decoding function, and the default encoding is utf-8, the code is as follows:

this.value = StringCoding.decode(bytes, offset, length);
 
 再点进decode,循序渐进发现,默认编码是UTF-8

Although the byte stream can also solve the garbled problem, it is still more troublesome, so java has a character stream, 字符为单位read and write data, and character stream 专门用于处理文本files. If the data processing plain text takes precedence over the character stream, other cases can only be streamed with bytes ( 只文本except for images, videos, etc. ).

From another perspective: character stream = byte stream + code table

1, character input stream (Reader)

java.io.ReaderAn abstract class is a superclass (parent) of all classes of a character input stream that can read character information into memory. It defines the basic commonality of the character input stream.

The common method of character input stream :

1. public void close()Close this stream and release any system resources associated with this stream.
2. public int read(): Read a character from the input stream.
3 public int read(char[] cbuf): some characters read from the input stream, and stores them in the character array cbufin

FileReader class

java.io.FileReaderA class is a convenience class for reading character files. The system default character encoding and default byte buffer are used in construction.

Construction method

1, FileReader(File file): Create a new FileReader, given the File object to be read .
2. FileReader(String fileName)Create a new FileReader giving the string name of the file to be read .

The use of the constructor should be familiar if you don’t write it. The code is as follows:

public class FileReaderConstructor throws IOException{
    public static void main(String[] args) {
        // 使用File对象创建流对象
        File file = new File("a.txt");
        FileReader fr = new FileReader(file);
      
        // 使用文件名称创建流对象
        FileReader fr = new FileReader("b.txt");
    }
}

FileReader reads character data

  1. Read characters : readmethod, each time you can read the data of one character, promote it to int type, read to the end of the file, return -1, loop read, code use demo:
public class FRRead {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileReader fr = new FileReader("a.txt");
        // 定义变量,保存数据
        int b ;
        // 循环读取
        while ((b = fr.read())!=-1) {
            System.out.println((char)b);
        }
        // 关闭资源
        fr.close();
    }
}

As for the reading, the writing is similar to the byte stream, except that the reading unit is different.

2, character output stream (Writer)

java.io.WriterThe abstract class is the superclass (parent class) of all classes of the character output stream , and writes the specified character information to the destination. It also defines the basic commonality of the character output stream.

The basic common function method of the character output stream :

1. void write(int c)Write a single character.
2. void write(char[] cbuf)Write a character array.
3, abstract void write(char[] cbuf, int off, int len)write a part of the character array, the starting index of the off array, the number of characters written by len.
4. void write(String str)Write a string.
5, void write(String str, int off, int len)write a part of the string, the start index of the off string, the number of characters written by len.
6. void flush()Refresh the buffer of the stream.
7. void close()Close the stream, but refresh it first.

FileWriter class

java.io.FileWriterA class is a convenience class for writing characters to a file. The system default character encoding and default byte buffer are used in construction.

Construction method

1, FileWriter(File file): Create a new FileWriter, given the File object to be read.
2 FileWriter(String fileName).: Create a new FileWriter, given the name of the file to be read.

Still a familiar construction example, the code is as follows:

public class FileWriterConstructor {
    public static void main(String[] args) throws IOException {
        // 第一种:使用File对象创建流对象
        File file = new File("a.txt");
        FileWriter fw = new FileWriter(file);
      
        // 第二种:使用文件名称创建流对象
        FileWriter fw = new FileWriter("b.txt");
    }
}

FileWriter writes data

Write the character : write(int b)method, each time you can write a character data, the code uses the demo:

public class FWWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileWriter fw = new FileWriter("fw.txt");     
        // 写出数据
        fw.write(97); // 写出第1个字符
        fw.write('b'); // 写出第2个字符
        fw.write('C'); // 写出第3个字符
        
        //关闭资源时,与FileOutputStream不同。 如果不关闭,数据只是保存到缓冲区,并未保存到文件。
        // fw.close();
    }
}
输出结果:
abC

[Note] When closing a resource, it is different from FileOutputStream. If not closed, the data is only saved to the buffer and not saved to the file.

Close close and refresh flush

Because of the built-in buffer, if you do not close the output stream, you cannot write characters to the file. However, the closed stream object cannot continue to write data. If we want to write data and want to continue using the stream, we need a flushmethod.

flush: Refresh the buffer and the stream object can continue to be used.
close: Flush the buffer first, then notify the system to release the resource. Stream objects can no longer be used.

Flush is still very interesting, children’s shoes do not run on their own really bad experience, now bloggers write a program for you to experience:
character stream

public class FlushDemo {
    public static void main(String[] args) throws Exception {
        //源   也就是输入流【读取流】 读取a.txt文件
        FileReader fr=new FileReader("a.txt");  //必须要存在a.txt文件,否则报FileNotFoundException异常
        //目的地  也就是输出流
        FileWriter fw=new FileWriter("b.txt");  //系统会自动创建b.txt,因为它是输出流!
        int len;
        while((len=fr.read())!=-1){
           fw.write(len);
        }
   注意这里是没有使用close关闭流,开发中不能这样做,但是为了更好的体会flush的作用
    }
}

IO_stream_operations_complete_of_Java_11.png

What is the effect of the operation? The answer is that the b.txt file is still empty, and there is nothing in it. Why? Bear dei, I have specifically marked it with a red font on it, which is the sentence: [Note] When closing a resource, it is different from FileOutputStream. If not closed, the data is only saved to the buffer and not saved to the file. This time the reaction came over, showing the importance of practical examples, programming is like this, don’t knock, never learn ! ! ! So be sure to knock, the blogger did not knock 100,000 lines of code, really no face to say that he is learning java. Therefore, everyone must think more and knock more! ! !

Therefore, we add the following three lines of code in the above code, it is perfect, b.txt file can be copied to the source file data!

  fr.close();
  fw.flush();
  fw.close();

flush()This function is the meaning of emptying, used to clear the data stream of the buffer. When the stream is operated, the data is first read into the memory, and then the data is written to the file, then when you finish reading the data, if we read this When the close()method is called to close the read and write stream, data loss may occur. Why? Because the completion of the read data does not mean that the write data is completed, and some of the data may remain in the buffer area. This flush()method is especially important.

Ok, then close to use the code as follows:

public class FWWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileWriter fw = new FileWriter("fw.txt");
        // 写出数据,通过flush
        fw.write('刷'); // 写出第1个字符
        fw.flush();
        fw.write('新'); // 继续写出第2个字符,写出成功
        fw.flush();
      
        // 写出数据,通过close
        fw.write('关'); // 写出第1个字符
        fw.close();
        fw.write('闭'); // 继续写出第2个字符,【报错】java.io.IOException: Stream closed
        fw.close();
    }
}

Even if the flush method writes the data, the close method is called to release the system resources.

FileWriter continuation and line breaks

Continued writing and newline : The operation is similar to the FileOutputStream operation (mentioned in the previous blog), directly on the code:

public class FWWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象,可以续写数据
        FileWriter fw = new FileWriter("fw.txt",true);     
        // 写出字符串
        fw.write("哥敢");
        // 写出换行
        fw.write("\r\n");
        // 写出字符串
        fw.write("摸屎");
        // 关闭资源
        fw.close();
    }
}
输出结果:
哥敢
摸屎

FileReader and FileWriter classes complete text file copying

Directly on the code:

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyFile {
    public static void main(String[] args) throws IOException {
        //创建输入流对象
        FileReader fr=new FileReader("F:\\新建文件夹\\aa.txt");//文件不存在会抛出java.io.FileNotFoundException
        //创建输出流对象
        FileWriter fw=new FileWriter("C:\\copyaa.txt");
        /*创建输出流做的工作:
         *      1、调用系统资源创建了一个文件
         *      2、创建输出流对象
         *      3、把输出流对象指向文件        
         * */
        //文本文件复制,一次读一个字符
        copyMethod1(fr, fw);
        //文本文件复制,一次读一个字符数组
        copyMethod2(fr, fw);
        
        fr.close();
        fw.close();
    }

    public static void copyMethod1(FileReader fr, FileWriter fw) throws IOException {
        int ch;
        while((ch=fr.read())!=-1) {//读数据
            fw.write(ch);//写数据
        }
        fw.flush();
    }

    public static void copyMethod2(FileReader fr, FileWriter fw) throws IOException {
        char chs[]=new char[1024];
        int len=0;
        while((len=fr.read(chs))!=-1) {//读数据
            fw.write(chs,0,len);//写数据
        }
        fw.flush();
    }
}

CopyFile

IO_stream_operations_complete_of_Java_12.png

Finally, emphasize again:
character stream, can only operate text files, can not operate pictures, video and other non-text files. Use character stream when we simply read or write text files, use byte stream in other cases

IO exception handling

We may be used to throwing exceptions in the process of learning, but in actual development, we can’t handle this. It is recommended to use try…catch…finallycode blocks to handle exceptions. The format code is as follows:

public class HandleException1 {
    public static void main(String[] args) {
        // 声明变量
        FileWriter fw = null;
        try {
            //创建流对象
            fw = new FileWriter("fw.txt");
            // 写出数据
            fw.write("哥敢摸si"); //哥敢摸si
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fw != null) {
                    fw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

If you are not particularly skilled in children’s shoes, you can refer to this article
[java basic exception] to die, try not to do the best, I am not happy!

Ok, here, the story of the character stream Reader and Writer is here!

I mainly wrote some basic streams as an introduction to IO streams. From here on, you will see some more powerful streams. For example, a buffer stream that can be efficiently read and written, a coded conversion stream, a serialized stream of storage objects, etc., and these powerful streams are based on basic stream objects! These powerful streams will be accompanied by our future development!

1, buffer flow [master]

1.1 Brief overview

First of all, let us know about the buffer stream, also called the high-efficiency stream, which is FileXxxthe “enhanced stream” of the four streams.

The basic principle of buffer flow :

1. Use the underlying stream object to get data from a specific device and store the data in an array of buffers.
2, through the buffer read () method to get specific character data from the buffer, which improves efficiency.
3. If the read data is read by the read method and stored in another container, until the newline is read, the data temporarily stored by the other container is converted into a string and returned, and the readLine() function is formed.

That is to say, when creating a stream object, a built-in buffer array of the default size is created, and the number of system IOs is reduced by reading and writing through the buffer, thereby improving the efficiency of reading and writing.

The buffer writing format is BufferedXxx, according to the data type:

  • Byte buffer stream : BufferedInputStream,BufferedOutputStream
  • Character buffer stream : BufferedReader,BufferedWriter

1.2 byte buffer stream

Construction method

  • public BufferedInputStream(InputStream in): Create a new buffered input stream, note that the parameter type is InputStream .
  • public BufferedOutputStream(OutputStream out): Create a new buffered output stream, noting that the parameter type is OutputStream .

The construction example code is as follows:

//构造方式一: 创建字节缓冲输入流【但是开发中一般常用下面的格式申明】
FileInputStream fps = new FileInputStream(b.txt);
BufferedInputStream bis = new BufferedInputStream(fps)

//构造方式一: 创建字节缓冲输入流
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("b.txt"));

///构造方式二: 创建字节缓冲输出流
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.txt"));

Feel the efficiency of the buffer flow

The buffer stream read and write method is consistent with the basic stream. We test its efficiency by copying large files of more than 370 MB.

  1. The basic stream, the code is as follows:
public class BufferedDemo {
    public static void main(String[] args) throws FileNotFoundException {
        // 记录开始时间
        long start = System.currentTimeMillis();
        // 创建流对象
        try (
            FileInputStream fis = new FileInputStream("py.exe");//exe文件够大
            FileOutputStream fos = new FileOutputStream("copyPy.exe")
        ){
            // 读写数据
            int b;
            while ((b = fis.read()) != -1) {
                fos.write(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("普通流复制时间:"+(end - start)+" 毫秒");
    }
}
不好意思十分钟过去了还在玩命复制中...
  1. Buffer stream, the code is as follows:
public class BufferedDemo {
    public static void main(String[] args) throws FileNotFoundException {
        // 记录开始时间
        long start = System.currentTimeMillis();
        // 创建流对象
        try (
         BufferedInputStream bis = new BufferedInputStream(new FileInputStream("py.exe"));
         BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copyPy.exe"));
        ){
        // 读写数据
            int b;
            while ((b = bis.read()) != -1) {
                bos.write(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("缓冲流复制时间:"+(end - start)+" 毫秒");
    }
}

缓冲流复制时间:8016 毫秒

Some children’s shoes are going to be said, I want faster speed! Recently, I saw that speed and passion 7 are a bit high. Can you be faster? The answer is of course

Want to use arrays faster, the code is as follows:

public class BufferedDemo {
    public static void main(String[] args) throws FileNotFoundException {
        // 记录开始时间
        long start = System.currentTimeMillis();
        // 创建流对象
        try (
         BufferedInputStream bis = new BufferedInputStream(new FileInputStream("py.exe"));
         BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copyPy.exe"));
        ){
            // 读写数据
            int len;
            byte[] bytes = new byte[8*1024];
            while ((len = bis.read(bytes)) != -1) {
                bos.write(bytes, 0 , len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("缓冲流使用数组复制时间:"+(end - start)+" 毫秒");
    }
}
缓冲流使用数组复制时间:521 毫秒  

1.3 character buffer stream

Construction method

The same is to look at its construction, its format and principle are the same as the byte buffer stream!

  • public BufferedReader(Reader in): Create a new buffered input stream, note that the parameter type is Reader .
  • public BufferedWriter(Writer out): Create a new buffered output stream, note that the parameter type is Writer .

Construction example, the code is as follows:

// 创建字符缓冲输入流
BufferedReader br = new BufferedReader(new FileReader("b.txt"));
// 创建字符缓冲输出流
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));

Character buffer stream specific method

The basic method of character buffer stream is consistent with the normal character stream calling method. I will not elaborate here. Let’s look at the unique method of character buffer stream .

  • BufferedReader: public String readLine(): Read a row of data . Return to null at the end of reading
  • BufferedWriter: public void newLine(): Wraps , defined by system properties.

readLineThe method demo code is as follows:

public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {
         // 创建流对象
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        // 定义字符串,保存读取的一行文字
        String line  = null;
        // 循环读取,读取到最后返回null
        while ((line = br.readLine())!=null) {
            System.out.print(line);
            System.out.println("------");
        }
        // 释放资源
        br.close();
    }
}

newLineThe method demo code is as follows:

public class BufferedWriterDemo throws IOException {
  public static void main(String[] args) throws IOException  {
      // 创建流对象
      BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
      // 写出数据
      bw.write("哥");
      // 写出换行
      bw.newLine();
      bw.write("敢");
      bw.newLine();
      bw.write("摸屎");
      bw.newLine();
      bw.write("你敢吗?");
      bw.newLine();
      // 释放资源
      bw.close();
  }
}
输出效果:
哥
敢
摸屎
你敢吗?

1.4 character buffer flow practice

Character buffer flow practice kneading? Let’s relax first, everyone, first appreciate the poems I wrote below.

6. You said that your program is simple. I said that my code is called Psalm
1. I think of you, I am arguing, arguing, arguing, arguing, arrogance, arbitrage, arbitrage, arbitrage.
Ca n’t stand 8.Just Simple you and me, Just simple programmer
3. Have a place to forget to meet, know how lonely to understand the vastness
5. Silence is the biggest say
2. Always like sitting in front of the computer, always like Work until late
7. Go left and go right, we turn a lot of bends
4. You never ask me, you are still not the programmer

Have you finished watching it? Yes, let’s practice how to use the buffer stream technology to order the above poems, and have been numbered ~ is the number from the previous 1 to 8 ~

Analysis: First, use the character input buffer stream to create a source, which has no sorted text, and then use the character output buffer stream to create a target to receive. The process of sorting must write its own method. It can be shared from each poem. Click the “.” symbol to start!

Code

public class BufferedTest {
    public static void main(String[] args) throws IOException {
        // 创建map集合,保存文本数据,键为序号,值为文字
        HashMap<String, String> lineMap = new HashMap<>();

        // 创建流对象  源
        BufferedReader br = new BufferedReader(new FileReader("a.txt"));
        //目标
        BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));

        // 读取数据
        String line  = null;
        while ((line = br.readLine())!=null) {
            // 解析文本
            String[] split = line.split("\\.");
            // 保存到集合
            lineMap.put(split[0],split[1]);
        }
        // 释放资源
        br.close();

        // 遍历map集合
        for (int i = 1; i <= lineMap.size(); i++) {
            String key = String.valueOf(i);
            // 获取map中文本
            String value = lineMap.get(key);
            // 写出拼接文本
            bw.write(key+"."+value);
            // 写出换行
            bw.newLine();
        }
        // 释放资源
        bw.close();
    }
}

running result

1.一想到你我就哦豁豁豁豁豁豁豁豁豁豁…哦nima个头啊,完全不理人家受得了受不了
2.总是喜欢坐在电脑前, 总是喜欢工作到很晚
3.约了地点却忘了见面 ,懂得寂寞才明白浩瀚
4.你从来就不问我,你还是不是那个程序员
5.沉默是最大的发言权
6.你说你的程序叫简单,我说我的代码叫诗篇
7.向左走 又向右走,我们转了好多的弯
8.Just 简单你和我 ,Just 简单程序员

2, conversion flow [master]

What is a conversion stream? Why is it coming? For the time being, let us first understand the character encoding and character set!
IO_stream_operations_complete_of_Java_13.png

2.1 Character encoding and decoding

As we all know, the information stored in the computer is represented by binary numbers, and the characters we see on the screen, such as numbers, English, punctuation marks, Chinese characters, etc., are the result of binary number conversion. According to some rules, characters are stored in a computer, called encoding . On the contrary, the binary number stored in the computer is parsed and displayed according to a certain rule, which is called decoding . For example, according to the Arules stored, also Aparsed according to the rules, then the correct text symbol can be displayed. Conversely, Astoring according to the rules and then Bparsing according to the rules will lead to garbled characters.

To put it simply:

Coding: characters (can understand) – bytes (do not understand)

Decoding: Bytes (Unreadable) –> Characters (can be understood)

The code explanation is

String(byte[] bytes, String charsetName):通过指定的字符集解码字节数组
byte[] getBytes(String charsetName):使用指定的字符集合把字符串编码为字节数组

编码:把看得懂的变成看不懂的
String -- byte[]

解码:把看不懂的变成看得懂的
byte[] -- String
  • Character Encoding Character Encoding : This is the correspondence between a set of natural language characters and binary numbers.

    The coding table is the corresponding rule for the characters in life and the binary in the computer.

character set

  • Character set Charset : Also called the code list . Is a collection of all characters supported by the system, including national text, punctuation, graphic symbols, numbers, and so on.

In order to accurately store and recognize various character set symbols, a computer needs to perform character encoding. A set of character sets must have at least one set of character encoding. Common character sets have ASCIIcharacter sets, GBKcharacter sets, Unicodecharacter sets, and so on.
IO_stream_operations_complete_of_Java_14.png

It can be seen that when the encoding is specified , the corresponding character set is naturally specified, so encoding is the ultimate concern of us.

  • ASCII character set :
    • ASCII (American Standard Code for Information Interchange) is a set of computer coding systems based on the Latin alphabet for displaying modern English, including control characters (carriage keys, backspace, line feed keys, etc.) and Display characters (English uppercase and lowercase characters, Arabic numerals, and Western symbols).
    • The basic ASCII character set uses 7 bits to represent a character for a total of 128 characters. The ASCII extended character set uses 8 bits to represent a character, a total of 256 characters, which is convenient for supporting European common characters.
  • ISO-8859-1 character set :
    • The Latin code table, alias Latin-1, is used to display the languages ​​spoken in Europe, including the Netherlands, Denmark, German, Italian, Spanish, etc.
    • ISO-8859-1 uses single-byte encoding and is compatible with ASCII encoding.
  • GBxxx character set :
    • GB is the meaning of the national standard, a set of characters designed to display Chinese.
    • GB2312 : Simplified Chinese code table. A character less than 127 has the same meaning as before. But when two characters larger than 127 are connected together, it means a Chinese character, so that it can be combined with more than 7000 simplified Chinese characters. In addition, mathematical symbols, Roman Greek letters, Japanese pseudonyms are compiled, and even in ASCII. The numbers, punctuation, and letters that were originally in existence are all re-encoded by two bytes long. This is the “full-width” character that is often said, and those that are below 127 are called “half-width” characters.
    • GBK : The most commonly used Chinese code table. It is an extension specification based on the GB2312 standard. It uses a two-byte encoding scheme. It contains 21,003 Chinese characters and is fully compatible with the GB2312 standard. It also supports traditional Chinese characters as well as Japanese and Korean characters.
    • GB18030 : The latest Chinese code table. The collection of Chinese characters 70,244, using multi-byte encoding, each word can be composed of 1, 2 or 4 bytes. Support Chinese national minority texts, and support traditional Chinese characters as well as Japanese and Korean characters.
  • Unicode character set :
    • The Unicode encoding system is designed to express any character in any language. It is a standard in the industry, also known as Unicode and standard Unicode.
    • It uses up to 4 bytes of numbers to represent each letter, symbol, or text. There are three encoding schemes, UTF-8, UTF-16 and UTF-32. The most commonly used UTF-8 encoding.
    • UTF-8 encoding, which can be used to represent any character in the Unicode standard. It is the preferred encoding for email, web pages, and other applications that store or transmit text. The Internet Engineering Task Force (IETF) requires all Internet protocols to support UTF-8 encoding. So, we develop web applications and also use UTF-8 encoding. It uses one to four bytes for each character encoding, encoding rules:
      1. 128 US-ASCII characters, only one byte encoding.
      2. Characters such as Latin require two bytes of encoding.
      3. Most common words (including Chinese) use three-byte encoding.
      4. Other rarely used Unicode auxiliary characters, using four-byte encoding.

2.2 Encoding problems lead to garbled characters

In the java development tool IDEA, use to FileReaderread the text file in the project. Since the IDEA settings are the default UTF-8encoding, there is no problem. However, when reading a text file created in the Windows system, garbled characters appear because the Windows system defaults to GBK encoding.

public class ReaderDemo {
    public static void main(String[] args) throws IOException {
        FileReader fileReader = new FileReader("C:\\a.txt");
        int read;
        while ((read = fileReader.read()) != -1) {
            System.out.print((char)read);
        }
        fileReader.close();
    }
}
输出结果:���

So how do you read a GBK encoded file? At this time, I have to talk about the conversion flow!

From another perspective: character stream = byte stream + code table

2.3 InputStreamReader class —– (Bitstream to character stream bridge)

The conversion stream java.io.InputStreamReader, Readera subclass of it, can be seen literally as a bridge from byte stream to character stream. It reads the bytes and decodes them into characters using the specified character set. Its character set can be specified by name or the platform’s default character set.

Construction method

InputStreamReader(InputStream in): Create a character stream that uses the default character set.
InputStreamReader(InputStream in, String charsetName): Creates a character stream of the specified character set.

The construction code is as follows:

InputStreamReader isr = new InputStreamReader(new FileInputStream("in.txt"));
InputStreamReader isr2 = new InputStreamReader(new FileInputStream("in.txt") , "GBK");

Use conversion streams to solve coding problems

public class ReaderDemo2 {
    public static void main(String[] args) throws IOException {
        // 定义文件路径,文件为gbk编码
        String FileName = "C:\\A.txt";
        // 创建流对象,默认UTF8编码
        InputStreamReader isr = new InputStreamReader(new FileInputStream(FileName));
        // 创建流对象,指定GBK编码
        InputStreamReader isr2 = new InputStreamReader(new FileInputStream(FileName) , "GBK");
        // 定义变量,保存字符
        int read;
        // 使用默认编码字符流读取,乱码
        while ((read = isr.read()) != -1) {
            System.out.print((char)read); // �����ʺ      
        }
        isr.close();
      
        // 使用指定编码字符流读取,正常解析
        while ((read = isr2.read()) != -1) {
            System.out.print((char)read);// 哥敢摸屎
        }
        isr2.close();
    }
}

2.4 OutputStreamWriter class —– (character stream to byte stream bridge)

The conversion stream java.io.OutputStreamWriteris a subclass of Writer. It is easy to be confused and literally thinks it is converted to a character stream. In fact, OutputStreamWriter is a bridge from character stream to byte stream. Encode characters into bytes using the specified character set. Its character set can be specified by name or the platform’s default character set.

Construction method

OutputStreamWriter(OutputStream in): Create a character stream that uses the default character set.
OutputStreamWriter(OutputStream in, String charsetName): Creates a character stream of the specified character set.

Construction example, the code is as follows:

OutputStreamWriter isr = new OutputStreamWriter(new FileOutputStream("a.txt"));
OutputStreamWriter isr2 = new OutputStreamWriter(new FileOutputStream("b.txt") , "GBK");

Specify encoding structure code

public class OutputDemo {
    public static void main(String[] args) throws IOException {
        // 定义文件路径
        String FileName = "C:\\s.txt";
        // 创建流对象,默认UTF8编码
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(FileName));
        // 写出数据
        osw.write("哥敢"); // 保存为6个字节
        osw.close();
        
        // 定义文件路径
        String FileName2 = "D:\\A.txt";
        // 创建流对象,指定GBK编码
        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream(FileName2),"GBK");
        // 写出数据
        osw2.write("摸屎");// 保存为4个字节
        osw2.close();
    }
}

IO_stream_operations_complete_of_Java_15.png

To achieve maximum efficiency , consider BufferedReaderpacking withinInputStreamReader

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

3, serialization flow [understand]

(1) The object can be written to a text file or transmitted over the network.
(2) How to implement serialization?
Let the serialized object belong to the class to implement the serialization interface.
This interface is a tag interface. No features need to be implemented.
(3) Attention to the problem:
After writing the data to the file, there will be a problem in modifying the class.
How to solve this problem?
In the class file, give a fixed serialized id value.
Moreover, this can also solve the yellow warning line problem
(4) interview question:
When is serialization?
How to achieve serialization?
What is deserialization?

3.1 What is serialization?

Java provides a mechanism for object serialization . A sequence of bytes can be used to represent an object that contains the information such as 对象的数据, , 对象的类型and so 对象中存储的属性on. After the byte sequence is written to the file, it is equivalent to persisting an object’s information in the file .

Conversely, the byte sequence can also be read back from the file, reconstructed, and deserialized . 对象的数据, 对象的类型and 对象中存储的数据information, can be used to create objects in memory. See the picture to understand serialization:
IO_stream_operations_complete_of_Java_16.png

3.2 ObjectOutputStream class

java.io.ObjectOutputStream Class, writes the original data type of the Java object to a file, and implements persistent storage of the object.

Construction method

public ObjectOutputStream(OutputStream out): Create an ObjectOutputStream that specifies the OutputStream.

The construction code is as follows:

FileOutputStream fileOut = new FileOutputStream("aa.txt");
ObjectOutputStream out = new ObjectOutputStream(fileOut);

Serialization operation

  1. To serialize an object, two conditions must be met:

This class must implement an java.io.Serializableinterface, which Serializableis a markup interface. Classes that do not implement this interface will not cause any state to be serialized or deserialized and will be thrown NotSerializableException.

All properties of this class must be serializable. If an attribute does not need to be serializable, the attribute must be noted as transient and transientdecorated with a keyword.

public class Employee implements java.io.Serializable {
    public String name;
    public String address;
    public transient int age; // transient瞬态修饰成员,不会被序列化
    public void addressCheck() {
        System.out.println("Address  check : " + name + " -- " + address);
    }
}

2. Write out the object method

public final void writeObject (Object obj) : Write out the specified object.

public class SerializeDemo{
    public static void main(String [] args)   {
        Employee e = new Employee();
        e.name = "zhangsan";
        e.address = "beiqinglu";
        e.age = 20; 
        try {
            // 创建序列化流对象
          ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("employee.txt"));
            // 写出对象
            out.writeObject(e);
            // 释放资源
            out.close();
            fileOut.close();
            System.out.println("Serialized data is saved"); // 姓名,地址被序列化,年龄没有被序列化。
        } catch(IOException i)   {
            i.printStackTrace();
        }
    }
}
输出结果:
Serialized data is saved

3.3 ObjectInputStream class

The ObjectInputStream deserializes the stream, restoring the original data that was previously serialized using ObjectOutputStream to an object.

Construction method

public ObjectInputStream(InputStream in): Create an ObjectInputStream that specifies an InputStream.

Deserialization operation 1

If we can find the class file of an object, we can perform the deserialization operation and call ObjectInputStreamthe method of reading the object:

  • public final Object readObject () : Read an object.
public class DeserializeDemo {
   public static void main(String [] args)   {
        Employee e = null;
        try {       
             // 创建反序列化流
             FileInputStream fileIn = new FileInputStream("employee.txt");
             ObjectInputStream in = new ObjectInputStream(fileIn);
             // 读取一个对象
             e = (Employee) in.readObject();
             // 释放资源
             in.close();
             fileIn.close();
        }catch(IOException i) {
             // 捕获其他异常
             i.printStackTrace();
             return;
        }catch(ClassNotFoundException c)  {
            // 捕获类找不到异常
             System.out.println("Employee class not found");
             c.printStackTrace();
             return;
        }
        // 无异常,直接打印输出
        System.out.println("Name: " + e.name);  // zhangsan
        System.out.println("Address: " + e.address); // beiqinglu
        System.out.println("age: " + e.age); // 0
    }
}

For a JVM you can deserialize an object, which must be a class that can find the class file. If you can not find this type of class file, then throw an ClassNotFoundExceptionexception.

Deserialization operation 2

In addition, when the JVM deserializes the object, the class file can be found, but the class file is modified after the serialized object, then the deserialization operation will also fail, throwing an InvalidClassExceptionexception. The reason for this exception is as follows:

1. The sequence version number of the class does not match the version number of the class descriptor read from the stream.
2. The class contains the unknown data type.
2. The class has no accessible parameterless constructor.

SerializableThe interface provides a sequence version number for the class that needs to be serialized. serialVersionUIDThe purpose of this version number is to verify that the serialized object and the corresponding class match.

public class Employee implements java.io.Serializable {
     // 加入序列版本号
     private static final long serialVersionUID = 1L;
     public String name;
     public String address;
     // 添加新的属性 ,重新编译, 可以反序列化,该属性赋为默认值.
     public int eid; 

     public void addressCheck() {
         System.out.println("Address  check : " + name + " -- " + address);
     }
}

3.4 Serialization Collection Exercise

  1. Save the collection serialization operation with multiple custom objects to a list.txtfile.
  2. Deserialize list.txtand traverse the collection to print object information.

case analysis

  1. Save several student objects to the collection.
  2. Serialize the collection.
  3. When deserializing a read, it only needs to be read once and converted to a collection type.
  4. Traverse the collection, you can print all student information

Case code implementation

public class SerTest {
    public static void main(String[] args) throws Exception {
        // 创建 学生对象
        Student student = new Student("老王", "laow");
        Student student2 = new Student("老张", "laoz");
        Student student3 = new Student("老李", "laol");

        ArrayList<Student> arrayList = new ArrayList<>();
        arrayList.add(student);
        arrayList.add(student2);
        arrayList.add(student3);
        // 序列化操作
        // serializ(arrayList);
        
        // 反序列化  
        ObjectInputStream ois  = new ObjectInputStream(new FileInputStream("list.txt"));
        // 读取对象,强转为ArrayList类型
        ArrayList<Student> list  = (ArrayList<Student>)ois.readObject();
        
        for (int i = 0; i < list.size(); i++ ){
            Student s = list.get(i);
            System.out.println(s.getName()+"--"+ s.getPwd());
        }
    }

    private static void serializ(ArrayList<Student> arrayList) throws Exception {
        // 创建 序列化流 
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt"));
        // 写出对象
        oos.writeObject(arrayList);
        // 释放资源
        oos.close();
    }
}

4, print stream [master]

4.1 What is a print stream?

Usually we print the output in the console, it is the calling printmethod and printlnmethod to complete, you have used such a long output statement certainly did not think that these two methods are from the java.io.PrintStreamclass, haha. This class is convenient for printing values ​​of various data types and is a convenient way to output.

Print stream classification :

Byte print stream PrintStream, character print stream PrintWriter

Print stream features :

A: Only operate the destination, do not operate the data source
B: Can operate any type of data
C: If automatic refresh is enabled, when the println() method is called, it can be wrapped and refreshed
D: the file can be directly manipulated

At this time, some students will ask, which streams can directly manipulate the file? The answer is very simple. If the constructor of the stream can receive parameters of type File and String at the same time, it is generally possible to directly manipulate the file !

PrintStream is a subclass of OutputStream, and PrintWriter is a subclass of Writer, both in the same position, so their APIs are very similar. The difference between the two is nothing more than a byte print stream, and one is a character print stream.

4.2 Byte Output Print Stream PrintStream Copy Text File

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintStream;

public class PrintStreamDemo {
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new FileReader("copy.txt"));
        PrintStream ps=new PrintStream("printcopy.txt");
        String line;
        while((line=br.readLine())!=null) {
            ps.println(line);
        }
        br.close();
        ps.close();
    }
}

4.3 Character Output Print Stream PrintWriter Copy Text File

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
/**
 * 使用打印流复制文本文件
 */
public class PrintWriterDemo {
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new FileReader("aa.txt"));
        PrintWriter pw=new PrintWriter("printcopyaa.txt");
        String line;
        while((line=br.readLine())!=null) {
            pw.println(line);
        }
        br.close();
        pw.close();
    }
}

5, Properties property class

I think you have been exposed to this Property class more or less. First, the Properties class is not in the IO package. What about the IO stream? The reason is simple because the properties class is often used in conjunction with the io stream.

(1) is a collection class, subclass of Hashtable
(2) unique function
A: public Object setProperty (String key, String value)
B: public String getProperty (String key)
C: public SetstringPropertyNames()
(3) Method of combining IO stream
Loading the contents of a text file in the form of a key-value pair into a collection
public void load(Reader reader)
public void load(InputStream inStream)
stores the data in the collection in a text file
public Void store(Writer writer, String comments)
public void store(OutputStream out, String comments)

5.1 Properties Overview

java.util.PropertiesInherited Hashtableto represent a persistent set of properties. It uses a key-value structure to store data, and each key and its corresponding value are a string. This class is also used by many Java classes. For example, when getting system properties, the System.getPropertiesmethod is to return an Propertiesobject.

5.2 Properties class

Construction method

public Properties() : Create an empty property list.

Basic storage method

  • public Object setProperty(String key, String value) : Save a pair of properties.
  • public String getProperty(String key) : Search for attribute values ​​using the keys specified in this property list.
  • public Set<String> stringPropertyNames() : A collection of names for all keys.
public class ProDemo {
    public static void main(String[] args) throws FileNotFoundException {
        // 创建属性集对象
        Properties properties = new Properties();
        // 添加键值对元素
        properties.setProperty("filename", "a.txt");
        properties.setProperty("length", "209385038");
        properties.setProperty("location", "D:\\a.txt");
        // 打印属性集对象
        System.out.println(properties);
        // 通过键,获取属性值
        System.out.println(properties.getProperty("filename"));
        System.out.println(properties.getProperty("length"));
        System.out.println(properties.getProperty("location"));

        // 遍历属性集,获取所有键的集合
        Set<String> strings = properties.stringPropertyNames();
        // 打印键值对
        for (String key : strings ) {
            System.out.println(key+" -- "+properties.getProperty(key));
        }
    }
}
输出结果:
{filename=a.txt, length=209385038, location=D:\a.txt}
a.txt
209385038
D:\a.txt
filename -- a.txt
length -- 209385038
location -- D:\a.txt

Flow related method

public void load(InputStream inStream): Reads a key-value pair from the byte input stream.

The byte input stream is used in the parameter, and the stream object can be associated with a file so that the data in the text can be loaded. The text data format is now as follows:

filename=Properties.txt
length=123
location=C:\Properties.txt

Load code demo:

public class ProDemo {
    public static void main(String[] args) throws FileNotFoundException {
        // 创建属性集对象
        Properties pro = new Properties();
        // 加载文本中信息到属性集
        pro.load(new FileInputStream("Properties.txt"));
        // 遍历集合并打印
        Set<String> strings = pro.stringPropertyNames();
        for (String key : strings ) {
            System.out.println(key+" -- "+pro.getProperty(key));
        }
     }
}
输出结果:
filename -- Properties.txt
length -- 123
location -- C:\Properties.txt

The data in the text must be a key-value pair form, which can be separated by spaces, equal signs, colons, and so on.

How to say it, the basic review of the io stream has come to an end, and I have a taste of it. Step by step, slowly summed up in practice! What’s more, I am still very low, still have a long way to go.

Now that jdk has reached 13, the io stream has changed a lot. There will be time to sort out from scratch, there will be a chance!

Finally, everyone is welcome to pay attention to my public number, to discuss technology, yearning for technology, and pursuing technology…

 

Orignal link:https://www.cnblogs.com/yichunguo/p/11775270.html