Fundamentals of Java: XV. IO flow

Posted by m00nz00mer on Sun, 16 Jan 2022 14:40:07 +0100

1. Use of File class

1.1. Instantiation of File class

  • java.io.File class: abstract representation of file and file directory path, which is platform independent
  • File can create, delete and rename files and directories, but file cannot access the file content itself. If you need to access the file content itself, you need to use input / output streams.
  • To represent a real File or directory in a Java program, there must be a File object, but a File object in a Java program may not have a real File or directory.
  • The File object can be passed as a parameter to the stream constructor

Use of File class

  • An object of the File class that represents a File or a File directory (commonly known as a folder)
  • The File class is declared in Java Under IO package
    • File(String filePath): create a file object with filePath as the path, which can be an absolute path or a relative path
    • File(String parentPath,String childPath): create a file object with parentPath as the parent path and childPath as the child path.
    • File(File parentFile,String childPath): creates a file object based on a parent file object and a child file path
  • The File class involves the creation, deletion, renaming, modification time, File size and other methods of files or File directories, and does not involve the operation of writing or reading File contents. If you need to read or write File contents, you must use IO stream to complete.
  • Objects of subsequent File classes are often passed as parameters to the stream constructor, indicating the "end point" of reading or writing.
  • route
    • Relative path: the specified path compared to a certain path.
    • Absolute path: the path to the file or file directory including the drive letter
  • path separator
    • windows:\\
    • unix:/
  • Java programs support cross platform operation, so the path separator should be used with caution.
  • To solve this problem, the File class provides a constant:
    • public static final String separator.
    • Separators are provided dynamically according to the operating system.
  • File file1= new File("d:\\Work\\info.txt");
  • File file2= new File("d:"+ File.separator+ "Work"+ File.separator+ "info.txt");
  • File file3= new File("d:/Work");
import org.junit.Test;
import java.io.File;

public class FileTest {

    @Test
    public void test(){
        //Constructor 1:
        File file1 = new File("hello.txt");//Relative to the current module
        File file2 = new File("F:\\java\\Work2\\JavaSenior\\day08\\num.txt");

        System.out.println(file1);
        System.out.println(file2);

        //Constructor 2:
        File file3 = new File("D:\\workspace_idea1","JavaSenior");
        System.out.println(file3);

        //Constructor 3:
        File file4 = new File(file3,"hi.txt");
        System.out.println(file4);
    }

}

1.2 common methods of File class 1

  • public String getAbsolutePath(): get absolute path
  • public String getPath(): get path
  • public String getName(): get the name
  • public String getParent(): get the directory path of the upper level file. If none, null is returned
  • public long length(): get the file length (i.e. the number of bytes). Cannot get the length of the directory.
  • public long lastModified(): gets the last modified time, in milliseconds
  • The following two methods apply to file directories:
    • public String[] list(): gets the name array of all files or file directories in the specified directory
    • public File[] listFiles(): get the File array of all files or File directories in the specified directory
  • public boolean renameTo(File dest): rename the file to the specified file path
    • For example: file1 Rename to (File2) as an example:
    • To return true, file1 must exist on the hard disk and file2 must not exist on the hard disk.
import org.junit.Test;

import java.io.File;
import java.util.Date;

public class FileTest {

    @Test
    public void test2(){
        File file = new File("Hello.txt");
        File file2 = new File("F:\\java\\Work2\\JavaSenior\\day08\\num.txt");

        System.out.println(file.getAbsolutePath());
        System.out.println(file.getPath());
        System.out.println(file.getName());
        System.out.println(file.getParent());
        System.out.println(file.length());
        System.out.println(new Date(file.lastModified()));

        System.out.println();

        System.out.println(file2.getAbsolutePath());
        System.out.println(file2.getPath());
        System.out.println(file2.getName());
        System.out.println(file2.getParent());
        System.out.println(file2.length());
        System.out.println(file2.lastModified());
    }

    @Test
    public void test3(){
        //File must exist!!!
        File file = new File("F:\\java\\Work2\\JavaSenior");

        String[] list = file.list();
        for(String s : list){
            System.out.println(s);
        }

        System.out.println();

        File[] files = file.listFiles();
        for(File f : files){
            System.out.println(f);
        }
    }

    @Test
    public void test4(){
        File file1 = new File("hello.txt");
        File file2 = new File("D:\\book\\num.txt");

        boolean renameTo = file2.renameTo(file1);
        System.out.println(renameTo);
    }
}

1.3 common methods of File class 2

  • public boolean isDirectory(): judge whether it is a file directory
  • public boolean isFile(): judge whether it is a file
  • public boolean exists(): judge whether it exists
  • public boolean canRead(): judge whether it is readable
  • public boolean canWrite(): judge whether it is writable
  • public boolean isHidden(): judge whether to hide
  • Create the corresponding file or file directory on the hard disk
    • public boolean createNewFile(): creates a file. If the file exists, it will not be created and false will be returned
    • public boolean mkdir(): creates a file directory. If this file directory exists, it will not be created. If the upper directory of this file directory does not exist, it will not be created.
    • public boolean mkdirs(): create a file directory. If this file directory exists, it will not be created. If the upper file directory does not exist, create it together
  • Delete files or file directories from disk
    • public boolean delete(): deletes files or folders
      • Delete precautions: delete in Java does not go to the recycle bin.
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.util.Date;

public class FileTest {

    @Test
    public void test5(){
        File file1 = new File("hello.txt");
        file1 = new File("hello1.txt");

        System.out.println(file1.isDirectory());
        System.out.println(file1.isFile());
        System.out.println(file1.exists());
        System.out.println(file1.canRead());
        System.out.println(file1.canWrite());
        System.out.println(file1.isHidden());

        System.out.println();

        File file2 = new File("D:\\book");
        file2 = new File("D:\\book1");
        System.out.println(file2.isDirectory());
        System.out.println(file2.isFile());
        System.out.println(file2.exists());
        System.out.println(file2.canRead());
        System.out.println(file2.canWrite());
        System.out.println(file2.isHidden());
    }

    @Test
    public void test6() throws IOException {
        File file1 = new File("hi.txt");
        if(!file1.exists()){
            //File creation
            file1.createNewFile();
            System.out.println("Created successfully");
        }else{//File exists
            file1.delete();
            System.out.println("Delete succeeded");
        }
    }

    @Test
    public void test7(){
        //Creation of file directory
        File file1 = new File("d:\\io\\io1\\io3");

        boolean mkdir = file1.mkdir();
        if(mkdir){
            System.out.println("Created successfully 1");
        }

        File file2 = new File("d:\\io\\io1\\io4");

        boolean mkdir1 = file2.mkdirs();
        if(mkdir1){
            System.out.println("Created successfully 2");
        }
        //To delete successfully, the io4 file directory cannot have subdirectories or files
        File file3 = new File("D:\\io\\io1\\io4");
        file3 = new File("D:\\io\\io1");
        System.out.println(file3.delete());
    }
}

2. IO stream principle and stream classification

2.1 IO flow principle

  • I/O is the abbreviation of Input/Output. I/O technology is a very practical technology for processing data transmission between devices. Such as reading / writing files, network communication, etc.
  • In Java programs, the input / output operation of data is carried out in the form of "stream".
  • java. Various "stream" classes and interfaces are provided under the IO package to obtain different kinds of data and input or output data through standard methods.
  • input: read external data (data from disk, optical disc and other storage devices) into the program (memory).
  • Output: output program (memory) data to disk, optical disc and other storage devices.

2.2 classification of flow

  • According to different operation data units, it is divided into byte stream (8 bit) and character stream (16 bit)
  • According to the flow direction of data flow, it is divided into input flow and output flow
  • According to the different roles of the flow, it can be divided into node flow and processing flow
Abstract base classByte streamCharacter stream
Input streamInputStreamReader
Output streamOutputStreamWriter
  • Java's IO stream involves more than 40 classes, which are actually very regular and derived from the following four abstract base classes.
  • The names of subclasses derived from these four classes are suffixed with their parent class names.

2.3 IO flow system

3. Node stream (or file stream)

3.1 basic operation of reading data in FileReader

read file

Create a stream object and load an existing file into the stream.

FileReaderfr= new FileReader(new File("Test.txt"));

Create an array of temporary data.

char[] ch= new char[1024];

Call the read method of the stream object to read the data in the stream into the array.

fr.read(ch);

Close the resource.

fr.close();
import org.junit.Test;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

/**
 * 1, Classification of flow:
 * 1.Operation data unit: byte stream, character stream
 * 2.Data flow direction: input flow and output flow
 * 3.Roles of flow: node flow and processing flow
 *
 * 2, Flow architecture
 * Abstract base class node stream (or file stream) buffer stream (a kind of processing stream)
 * InputStream     FileInputStream   (read(byte[] buffer))        BufferedInputStream (read(byte[] buffer))
 * OutputStream    FileOutputStream  (write(byte[] buffer,0,len)  BufferedOutputStream (write(byte[] buffer,0,len) / flush()
 * Reader          FileReader (read(char[] cbuf))                 BufferedReader (read(char[] cbuf) / readLine())
 * Writer          FileWriter (write(char[] cbuf,0,len)           BufferedWriter (write(char[] cbuf,0,len) / flush()
 */
public class FileReaderWriterTest {
    public static void main(String[] args) {
        File file = new File("hello.txt");//Compared with the current project
        System.out.println(file.getAbsolutePath());

        File file1 = new File("day09\\hello.txt");
        System.out.println(file1.getAbsolutePath());
    }

    /**
     * Put hello. Under day09 Txt file content is read into the program and output to the console
     *
     * Description points:
     *     1. read()Return a character read in. If the end of the file is reached, - 1 is returned
     *     2. Exception handling: to ensure that flow resources can be closed. Try catch finally processing is required
     *     3. The read file must exist, otherwise FileNotFoundException will be reported.
     *
     */
    @Test
    public void test(){
        FileReader fr = null;
        try {
            //Instantiate the File object to indicate the File to be operated on
            File file = new File("hello.txt");//Compared to the current Module
            //2. Provide specific flow
            fr = new FileReader(file);

            //3. Data reading process
            //read(): returns a character read in. If the end of the file is reached, return - 1
            //Mode 1:
//        int data = fr.read();
//        while(data != -1){
//            System.out.print((char) data);
//            data = fr.read();
//        }

            //Mode 2: grammatical modification of mode 1
            int data;
            while((data = fr.read()) != -1){
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //4. Close the flow
//            try {
//                if(fr != null)
//                    fr.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }

            //or
            if(fr != null){
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

3.2 read(char[] cbuf) is used in FileReader to read data

import org.junit.Test;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class FileReaderWriterTest {

    //Upgrade the read() operation: use the overloaded method of read
    @Test
    public void test2(){
        FileReader fr = null;
        try {
            //1. Instantiation of file class
            File file = new File("hello.txt");

            //2. Instantiation of FileReader stream
            fr = new FileReader(file);

            //3. Read in operation
            //read(char[] cbuf): returns the number of characters read into the cbuf array each time. If the end of the file is reached, - 1 is returned
            char[] cbuf = new char[5];
            int len;
            fr.read(cbuf);
            while((len = fr.read(cbuf)) != -1){
                //Mode 1:
                //Wrong writing
//                for(int i = 0;i < cbuf.length;i++){
//                    System.out.print(cbuf[i]);
//                }
                //Correct writing
//                for(int i = 0;i < len;i++){
//                    System.out.print(cbuf[i]);
//                }

                //Mode 2:
                //The wrong way of writing corresponds to the wrong way of writing in mode 1
//                String str = new String(cbuf);
//                System.out.print(str);
                //Correct writing
                String str = new String(cbuf,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fr != null){
                //4. Closure of resources
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

    }

}

3.3. Write out data by FileWriter

write file

Create a stream object and create a data storage file

FileWriterfw= new FileWriter(new File("Test.txt"));

Call the write method of the stream object to write data to the stream

fw.write("atguigu-songhongkang");

Close the stream resource and empty the data in the stream into the file.

fw.close();
import org.junit.Test;
import java.io.*;

public class FileReaderWriterTest {

    /**
     * Write data from memory to a file on the hard disk.
     *
     * explain:
     * 1.For output operation, the corresponding File may not exist. No exception will be reported
     * 2.
     *   File If the file in the corresponding hard disk does not exist, this file will be automatically created during output.
     *   File If the file in the corresponding hard disk exists:
     *       If the constructor used by the stream is: FileWriter(file,false) / FileWriter(file): overwrite the original file
     *       If the constructor used by the stream is: FileWriter(file,true): the original file will not be overwritten, but content will be added on the basis of the original file
     */
    @Test
    public void test3(){        
        FileWriter fw = null;
        try {
            //1. Provide the object of File class to indicate the File to be written out
            File file = new File("hello1.txt");

            //2. Provide FileWriter object for data writing
            fw = new FileWriter(file,false);

            //3. Write out the operation
            fw.write("I have a dream!\n");
            fw.write("you need to have a dream!");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. Closing of flow resources
            if(fw != null){

                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.4. Use FileReader and FileWriter to copy text files

import org.junit.Test;
import java.io.*;

public class FileReaderWriterTest {

    @Test
    public void test4() {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            //1. Create an object of File class to indicate the read in and write out files
            File srcFile = new File("hello1.txt");
            File srcFile2 = new File("hello2..txt");

            //Character streams cannot be used to process byte data such as pictures
//            File srcFile = new File("love and friendship. jpg");
//            File srcFile2 = new File("love and friendship 1.jpg");

            //2. Create objects for input and output streams
            fr = new FileReader(srcFile);
            fw = new FileWriter(srcFile2);

            //3. Read and write data
            char[] cbuf = new char[5];
            int len;//Record the number of characters read into the cbuf array each time
            while((len = fr.read(cbuf)) != -1){
                //Write len characters at a time
                fw.write(cbuf,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. Close stream resources
            //Mode 1:
//            try {
//                if(fw != null)
//                    fw.close();
//            } catch (IOException e) {
//                e.printStackTrace();
//            }finally{
//                try {
//                    if(fr != null)
//                        fr.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
            //Mode 2:
            try {
                if(fw != null)
                    fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                if(fr != null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

3.5 test that text files cannot be read using FileInputStream

import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * Test the use of FileInputStream and FileOutputStream
 *
 * Conclusion:
 *    1. For text files (. txt,.java,.c,.cpp), use character stream processing
 *    2. For non text files (. jpg,.mp3,.mp4,.avi,.doc,.ppt,...), Using byte stream processing
 */
public class FileIOPutTest {
    //Using byte stream FileInputStream to process text files may cause garbled code.
    @Test
    public void testFileInputStream(){
        FileInputStream fis = null;
        try {
            //1. Documentation
            File file = new File("hello.txt");

            //2. Flow generation
            fis = new FileInputStream(file);

            //3. Read data
            byte[] buffer = new byte[5];
            int len;//Record the number of bytes read each time
            while((len = fis.read(buffer)) != -1){
                String str = new String(buffer,0,len);
                System.out.print(str);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fis != null) {
                //4. Close resources
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3.6. Use FileInputStream and FileOutputStream to read and write non text files

import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileIOPutTest {

    /**
     * Copy the picture
     */
    @Test
    public void testFileInputOutputStream()  {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //1. Documentation
            File srcFile = new File("Love and friendship.jpg");
            File destFile = new File("Love and friendship 2.jpg");

            //2. Flow generation
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);

            //3. Copy process
            byte[] buffer = new byte[5];
            int len;
            //4. Read data
            while((len = fis.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }
            System.out.println("Copy succeeded");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fos != null){
                //5. Close resources
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }

    }
}

3.7. Method test of copying files using FileInputStream and FileOutputStream

import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class FileIOPutTest {

    //Copy of files under the specified path
    public void copyFile(String srcPath,String destPath){
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //
            File srcFile = new File(srcPath);
            File destFile = new File(destPath);

            //
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);

            //Replication process
            byte[] buffer = new byte[1024];
            int len;
            while((len = fis.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fos != null){
                //
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fis != null){
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }

    @Test
    public void testCopyFile(){

        long start = System.currentTimeMillis();

//        String srcPath = "C:\\Users\\29433\\Desktop\\164.jpg";
//        String destPath = "C:\\Users\\29433\\Desktop\\164.jpg";

        String srcPath = "hello.txt";
        String destPath = "hello3.txt";

        copyFile(srcPath,destPath);

        long end = System.currentTimeMillis();

        System.out.println("The time taken for the copy operation is:" + (end - start));//1
    }
}

4. Buffer stream

In order to improve the speed of data reading and writing, the Java API provides stream classes with buffering function. When using these stream classes, an internal buffer array will be created. By default, a buffer of 8192 bytes (8Kb) is used.

  • The buffer flow should be "nested" on the corresponding node flow. According to the data operation unit, the buffer flow can be divided into:
    • BufferedInputStream and BufferedOutputStream
    • BufferedReader and BufferedWriter
  • When reading data, the data is read into the buffer by block, and subsequent read operations directly access the buffer
  • When using BufferedInputStream to read a byte file, BufferedInputStream will read 8192 bytes (8Kb) from the file at one time and store them in the buffer. It will not read the next 8192 byte array from the file until the buffer is full.
  • When writing bytes to the stream, they will not be directly written to the file. They will be written to the buffer first. BufferedOutputStream will not write the data in the buffer to the file at one time until the buffer is full. Use the method flush() to force all the contents of the buffer to be written to the output stream
  • The order in which the flow is closed is opposite to the order in which it is opened. Just turn off the outermost flow, and turning off the outermost flow will turn off the inner node flow accordingly
  • Use of the flush() method: manually write the contents of the buffer to the file
  • If it is the close() method of a stream object with buffer, it will not only close the stream, but also refresh the buffer before closing the stream. After closing, it can't be written out again.

4.1. The buffer stream (byte type) realizes the copy of non text files

import org.junit.Test;

import java.io.*;

/**
 * One of the processing streams: the use of buffer streams
 *
 *  1.Buffer stream:
 *  BufferedInputStream
 *  BufferedOutputStream
 *  BufferedReader
 *  BufferedWriter
 */
public class BufferedTest {

    /**
     * Copy non text files
     */
    @Test
    public void BufferedStreamTest(){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            //1. Documentation
            File srcFile = new File("Love and friendship.jpg");
            File destFile = new File("Love and friendship 3.jpg");
            //2. Flow generation
            //2.1 node flow
            FileInputStream fis = new FileInputStream((srcFile));
            FileOutputStream fos = new FileOutputStream(destFile);
            //2.2 buffer flow
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //3. Copy details: read, write
            byte[] buffer = new byte[10];
            int len;
            while((len = bis.read(buffer)) != -1){
                bos.write(buffer,0,len);
//                bos.flush();// refresh buffer 
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. Resource shutdown
            //Requirements: first close the flow of the outer layer, and then close the flow of the inner layer
            if(bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if(bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //Note: when the outer layer flow is closed, the inner layer flow will be closed automatically. The closure of inner laminar flow can be omitted
//        fos.close();
//        fis.close();
        }
    }
}

4.2 comparison of read and write speeds of buffer stream and node stream

import org.junit.Test;
import java.io.*;
/**
 * One of the processing streams: the use of buffer streams
 *
 *  1.Buffer stream:
 *  BufferedInputStream
 *  BufferedOutputStream
 *  BufferedReader
 *  BufferedWriter
 *
 *  2.Function: provides the read and write speed of the stream
 *    Reason for improving read and write speed: a buffer is provided internally
 *
 *  3. Processing flow is "socket" based on the existing flow.
 *
 */
public class BufferedTest {

    //Method for realizing file copying
    public void copyFileWithBuffered(String srcPath,String destPath){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
            //1. Documentation
            File srcFile = new File(srcPath);
            File destFile = new File(destPath);
            //2. Flow generation
            //2.1 node flow
            FileInputStream fis = new FileInputStream((srcFile));
            FileOutputStream fos = new FileOutputStream(destFile);
            //2.2 buffer flow
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(fos);

            //3. Copy details: read, write
            byte[] buffer = new byte[1024];
            int len;
            while((len = bis.read(buffer)) != -1){
                bos.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. Resource shutdown
            //Requirements: first close the flow of the outer layer, and then close the flow of the inner layer
            if(bos != null){
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if(bis != null){
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            //Note: when the outer layer flow is closed, the inner layer flow will be closed automatically. The closure of inner laminar flow can be omitted
//        fos.close();
//        fis.close();
        }
    }

    @Test
    public void testCopyFileWithBuffered(){
        long start = System.currentTimeMillis();

        String srcPath = "C:\\Users\\29433\\Desktop\\book.flv";
        String destPath = "C:\\Users\\29433\\Desktop\\book1.flv";


        copyFileWithBuffered(srcPath,destPath);


        long end = System.currentTimeMillis();

        System.out.println("The time taken for the copy operation is:" + (end - start));//1
    }

}

4.3. The buffer stream (character type) realizes the copy of text files

import org.junit.Test;
import java.io.*;

public class BufferedTest {
  /**
     * Use BufferedReader and BufferedWriter to copy text files
     */
    @Test
    public void test4(){
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            //Create files and corresponding streams
            br = new BufferedReader(new FileReader(new File("dbcp.txt")));
            bw = new BufferedWriter(new FileWriter(new File("dbcp1.txt")));

            //Read / write operation
            //Method 1: use char [] array
//            char[] cbuf = new char[1024];
//            int len;
//            while((len = br.read(cbuf)) != -1){
//                bw.write(cbuf,0,len);
//    //            bw.flush();
//            }

            //Method 2: use String
            String data;
            while((data = br.readLine()) != null){
                //Method 1:
//                bw.write(data + "\n");//data does not contain line breaks
                //Method 2:
                bw.write(data);//data does not contain line breaks
                bw.newLine();//Provides line feed operations
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //close resource
            if(bw != null){

                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

5. Conversion flow

5.1 overview of conversion flow and use of InputStreamReader

  • Conversion stream provides conversion between byte stream and character stream
  • The Java API provides two transformation flows:
    • InputStreamReader: convert InputStream to Reader
      • The input stream of bytes is converted into the input stream of characters according to the specified character set.
      • Need to "socket" with InputStream.
      • constructor
        • public InputStreamReader(InputStreamin)
        • public InputSreamReader(InputStreamin,StringcharsetName)
        • For example: Reader isr= new InputStreamReader(System.in, "gbk");
    • OutputStreamWriter: converts the Writer to OutputStream
      • The output stream of characters is converted into the output stream of bytes according to the specified character set.
      • Need to "socket" with OutputStream.
      • constructor
        • public OutputStreamWriter(OutputStreamout)
        • public OutputSreamWriter(OutputStreamout,StringcharsetName)
  • When the data in the byte stream is all characters, the operation of converting to character stream is more efficient.
  • Many times, we use transform stream to deal with the problem of file scrambling. Realize the functions of encoding and decoding.

import org.junit.Test;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Processing flow 2: use of conversion flow
 * 1.Conversion stream: belongs to character stream
 *      InputStreamReader: Converts a byte input stream to a character input stream
 *      OutputStreamWriter: Converts a character output stream to a byte output stream
 *
 * 2.Function: provide conversion between byte stream and character stream
 *
 * 3.Decoding: byte, byte array -- > character array, string
 *   Encoding: character array, string -- > byte, byte array
 *
 * 4.character set
 */
public class InputStreamReaderTest {

    /**
     * Try catch finally should still be used to handle exceptions at this time
     * InputStreamReader To realize the conversion from byte input stream to character input stream
     */
    @Test
    public void test() throws IOException {

        FileInputStream fis = new FileInputStream("dbcp.txt");
//        InputStreamReader isr = new InputStreamReader(fis);// Use the system default character set
        //Parameter 2 indicates the character set. The specific character set depends on the file DBCP Txt character set used when saving
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");//Use the system default character set

        char[] cbuf = new char[20];
        int len;
        while((len = isr.read(cbuf)) != -1){
            String str = new String(cbuf,0,len);
            System.out.print(str);
        }

        isr.close();
    }

}

5.2. Read in and write out of conversion stream implementation files

import org.junit.Test;

import java.io.*;

/**
 * Processing flow 2: use of conversion flow
 * 1.Conversion stream: belongs to character stream
 *      InputStreamReader: Converts a byte input stream to a character input stream
 *      OutputStreamWriter: Converts a character output stream to a byte output stream
 *
 * 2.Function: provide conversion between byte stream and character stream
 *
 * 3.Decoding: byte, byte array -- > character array, string
 *   Encoding: character array, string -- > byte, byte array
 *
 * 4.character set
 */
public class InputStreamReaderTest {
    /**
     * Try catch finally should still be used to handle exceptions at this time
     * Use InputStreamReader and OutputStreamWriter together
     */
    @Test
    public void test2() throws IOException {
        //1. Document making and flow making
        File file1 = new File("dbcp.txt");
        File file2 = new File("dbcp_gbk.txt");

        FileInputStream fis = new FileInputStream(file1);
        FileOutputStream fos = new FileOutputStream(file2);

        InputStreamReader isr = new InputStreamReader(fis,"utf-8");
        OutputStreamWriter osw = new OutputStreamWriter(fos,"gbk");

        //2. Reading and writing process
        char[] cbuf = new char[20];
        int len;
        while((len = isr.read(cbuf)) != -1){
            osw.write(cbuf,0,len);
        }

        //3. Close resources
        isr.close();
        osw.close();
    }
}

5.3 description of multiple character coding sets

  • Origin of coding table
    • Computers can only recognize binary data, which originated from electrical signals in the early days. In order to facilitate the application of the computer, it can recognize the characters of various countries. The words of each country are expressed in numbers and correspond one by one to form a table. This is the coding table.
  • Common coding table
    • ASCII: American standard information interchange code.
      • It can be represented by 7 bits of a byte.
    • ISO8859-1: Latin code table. European code table
      • Represented by 8 bits of a byte.
    • GB2312: Chinese coding table of China. Up to two bytes encode all characters
    • GBK: China's Chinese coding table has been upgraded to integrate more Chinese characters and symbols. Up to two byte encoding
    • Unicode: international standard code, which integrates all characters currently used by human beings. Assign a unique character code to each character.
      • All text is represented by two bytes.
    • UTF-8: variable length encoding method. 1-4 bytes can be used to represent a character.
  • explain
    • Unicode is not perfect. Here are three problems
      • The first problem is that we already know that only one byte is enough for English letters,
      • The second question is, how can I distinguish Unicode from ASCII? How does the computer know that two bytes represent one symbol instead of two symbols respectively?
      • The third problem is that if, like the double byte encoding method such as GBK, the highest bit is 1 or 0 to represent two bytes and one byte, there are many fewer values, which can not be used to represent characters, not enough to represent all characters. Unicode could not be popularized for a long time until the emergence of the Internet.
    • Many transmission oriented UTF (UCS Transfer Format) standards have emerged. As the name suggests, * * UTF-8 transmits data 8 bits at a time, while UTF-16 transmits data 16 bits at a time** This is a code designed for transmission and makes the code borderless, so that the characters of all cultures in the world can be displayed.
    • Unicode only defines a huge and universal character set, and specifies a unique number for each character. The specific byte stream stored depends on the character encoding scheme. The recommended Unicode encodings are UTF-8 and UTF-16.

6. Standard input and output streams

  • System.in and system Out represents the input and output devices of the system standard respectively
  • The default input device is keyboard, and the output device is display
  • System. The type of in is InputStream
  • System. The type of out is PrintStream, which is a subclass of OutputStream and a subclass of FilterOutputStream
  • Change the default method of setIn and setOut.
    • public static void setIn(InputStreamin)
    • public static void setOut(PrintStreamout)
import org.junit.Test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Use of other streams
 * 1.Standard input and output streams
 * 2.Print stream
 * 3.data stream
 */
public class OtherStreamTest {

    /**
     * 1.Standard input and output streams
     *   1.1
     *     System.in:Standard input stream, input from the keyboard by default
     *     System.out:The standard output stream is output from the console by default
     *   1.2
     *     System Class to reassign the input and output streams in the setIn(InputStream is) / setOut(PrintStream ps) mode.
     *
     *   1.3 practice:
     *     Input the string from the keyboard, and it is required to convert the read whole line of string into uppercase output. Then continue the input operation,
     *     Until you enter "e" or "exit", exit the program.
     *
     *   Method 1: using the Scanner implementation, call next() to return a string
     *   Method 2: use system In implementation. System.in -- > Transform stream -- > readLine() of BufferedReader
     */
    @Test
    public void test(){
        BufferedReader br = null;
        try {
            InputStreamReader isr = new InputStreamReader(System.in);
            br = new BufferedReader(isr);

            while (true) {
                System.out.println("Please enter a string:");
                String data = br.readLine();
                if ("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)) {
                    System.out.println("Program end");
                    break;
                }

                String upperCase = data.toUpperCase();
                System.out.println(upperCase);

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

7. Print stream

  • The data format of the basic data type is converted to string output
  • Print streams: PrintStream and PrintWriter
    • Provides a series of overloaded print() and println() methods for output of multiple data types
    • The output of PrintStream and PrintWriter will not throw IOException
    • PrintStream and PrintWriter have automatic flush function
    • All characters printed by PrintStream are converted to bytes using the platform's default character encoding. When you need to write characters instead of bytes, you should use the PrintWriter class.
    • System.out returns an instance of PrintStream
import org.junit.Test;
import java.io.*;

public class OtherStreamTest {

    /**
     * 2. Print streams: PrintStream and PrintWriter
     *  2.1 Provides a series of overloaded print() and println()
     *  2.2 practice:
     */
    @Test
    public void test2(){
        PrintStream ps = null;
        try {
            FileOutputStream fos = new FileOutputStream(new File("D:\\IO\\text.txt"));
            // Create a printout stream and set it to automatic refresh mode (the output buffer will be refreshed when a newline character or byte '\ n' is written)
            ps = new PrintStream(fos, true);
            if (ps != null) {// Change the standard output stream (console output) to a file
                System.setOut(ps);
            }

            for (int i = 0; i <= 255; i++) { // Output ASCII characters
                System.out.print((char) i);
                if (i % 50 == 0) { // Every 50 data rows
                    System.out.println(); // Line feed
                }
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (ps != null) {
                ps.close();
            }
        }
    }
}

8. Data flow

  • In order to easily manipulate the basic data types of Java language and String data, you can use data flow.

  • Data flow has two classes: (used to read and write data of basic data type and String class)

    • DataInputStream and DataOutputStream
    • "Socket" on the streams of subclasses InputStream and OutputStream respectively
  • Methods in DataInputStream

boolean readBoolean()	byte readByte()
char readChar()	float readFloat()
double readDouble()	short readShort()
long readLong()	int readInt()
String readUTF()	void readFully(byte[s] b)
  • Methods in DataOutputStream
  • Change the read of the above method to the corresponding write.
import org.junit.Test;
import java.io.*;

public class OtherStreamTest {    
   /**
     * 3.data stream
     *   3.1 DataInputStream And DataOutputStream
     *   3.2 Function: used to read or write variables or strings of basic data types
     *
     *   Exercise: write out strings in memory and variables of basic data types to files.
     *
     *   Note: try catch finally should still be used to handle exceptions
     */
    @Test
    public void test3() throws IOException {
        //1.
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));
        //2.
        dos.writeUTF("Liu Gang");
        dos.flush();//Refresh operation to write the data in memory to the file
        dos.writeInt(23);
        dos.flush();
        dos.writeBoolean(true);
        dos.flush();
        //3.
        dos.close();
    }

    /**
     * Read the basic data type variables and strings stored in the file into memory and save them in variables.
     *
     * Note: the order of reading different types of data should be consistent with the order of saved data when writing the file!
     */
    @Test
    public void test4() throws IOException {
        //1.
        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));
        //2.
        String name = dis.readUTF();
        int age = dis.readInt();
        boolean isMale = dis.readBoolean();

        System.out.println("name = " + name);
        System.out.println("age = " + age);
        System.out.println("isMale = " + isMale);

        //3.
        dis.close();

    }
}

9. Object flow

9.1 understanding of object serialization mechanism

  • ObjectInputStream and ojbectoutputstream
  • A processing stream used to store and read basic data type data or objects. Its strength is that it can write objects in Java to the data source and restore objects from the data source.
  • Serialization: a mechanism for holding basic type data or objects with the ObjectOutputStream class
  • Deserialization: a mechanism for reading basic type data or objects with the ObjectInputStream class
  • ObjectOutputStream and ObjectInputStream cannot serialize static and transient decorated member variables
  • The object serialization mechanism allows Java objects in memory to be converted into platform independent binary streams, which allows such binary streams to be permanently stored on disk or transmitted to another network node through the network// When other programs get this binary stream, they can restore it to the original Java object
  • The advantage of serialization is that it can convert any object that implements the Serializable interface into byte data, so that it can be restored during saving and transmission
  • Serialization is a mechanism that must be implemented for both parameters and return values of RMI (Remote Method Invoke), and RMI is the basis of Java EE. Therefore, serialization mechanism is the foundation of Java EE platform
  • If an object needs to support serialization mechanism, the class to which the object belongs and its properties must be serializable. In order for a class to be serializable, the class must implement one of the following two interfaces. Otherwise, a NotSerializableException is thrown
    • Serializable
    • Externalizable

9.2. Object stream serialization and deserialization string operations

import org.junit.Test;

import java.io.*;

/**
 * Use of object streams
 * 1.ObjectInputStream And ObjectOutputStream
 * 2.Function: a processing stream used to store and read basic data type data or objects. Its strength is that it can write objects in Java to the data source and restore objects from the data source.
 */
public class ObjectTest {

    /**
     * Serialization process: save java objects in memory to disk or transfer them over the network
     * Implementation using ObjectOutputStream
     */
    @Test
    public void test(){
        ObjectOutputStream oos = null;
        try {
            //Creative flow
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
            //Manufacturing object
            oos.writeObject(new String("Welcome to Qinshihuang Mausoleum"));

            //Refresh operation
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(oos != null){
                //3. Close the flow
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Deserialization: restore the object in the disk file to a java object in memory
     * Using ObjectInputStream to implement
     */
    @Test
    public void test2(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("object.dat"));

            Object obj = ois.readObject();
            String str = (String) obj;

            System.out.println(str);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

9.3. The user-defined class implements serialization and deserialization operations

  • If a class implements the Serializable interface, the object of the class is Serializable:

    • Create an ObjectOutputStream
    • Call the writeobject (object) method of the ObjectOutputStream object to output the serializable object
    • Note that write once and operate flush() once
  • Deserialization

    • Create an ObjectInputStream object and call the readObject() method to read the objects in the stream
  • Stress: if the attribute of a class is not a basic data type or String type, but another reference type, the reference type must be serializable, otherwise the class with the Field of this type cannot be serialized

Person class

import java.io.Serializable;

/**
 * Person The following requirements must be met before serialization
 * 1.Interface to be implemented: Serializable
 */
public class Person implements Serializable {
    public static final long serialVersionUID = 475463534532L;

    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", 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;
    }
}

Test class

import org.junit.Test;

import java.io.*;

/**
 * Use of object streams
 * 1.ObjectInputStream And ObjectOutputStream
 * 2.Function: a processing stream used to store and read basic data type data or objects. Its strength is that it can write objects in Java to the data source and restore objects from the data source.
 *
 * 3.If you want a Java object to be serializable, you need to meet the corresponding requirements. See person java
 *
 * 4.Serialization mechanism:
 * The object serialization mechanism allows Java objects in memory to be converted into platform independent binary streams, which allows this
 * The binary stream is persisted on disk or transmitted to another network node through the network.
 * When other programs get this binary stream, they can restore it to the original Java object.
 *
 */
public class ObjectTest {

    /**
     * Serialization process: save java objects in memory to disk or transfer them over the network
     * Implementation using ObjectOutputStream
     */
    @Test
    public void test(){
        ObjectOutputStream oos = null;
        try {
            //Creative flow
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
            //Manufacturing object
            oos.writeObject(new String("Welcome to Qinshihuang Mausoleum"));
            //Refresh operation
            oos.flush();

            oos.writeObject(new Person("Li Shizhen",65));
            oos.flush();


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(oos != null){
                //3. Close the flow
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Deserialization: restore the object in the disk file to a java object in memory
     * Using ObjectInputStream to implement
     */
    @Test
    public void test2(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("object.dat"));

            Object obj = ois.readObject();
            String str = (String) obj;

            Person p = (Person) ois.readObject();

            System.out.println(str);
            System.out.println(p);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

9.4 understanding of serialVersionUID

  • All classes that implement the Serializable interface have a static variable that represents the serialized version identifier:
    • private static final long serialVersionUID;
    • serialVersionUID is used to indicate compatibility between different versions of a class. In short, its purpose is to use serialized objects for version control, and whether each version is compatible when deserialized.
    • If the class does not show the definition of this static constant, its value is automatically generated by the Java runtime environment according to the internal details of the class. If the instance variable of the class is modified, the serialVersionUID may change. Therefore, it is recommended to explicitly declare.
  • In short, the serialization mechanism of Java verifies the version consistency by judging the serialVersionUID of the class at run time. During deserialization, the JVM will compare the serialVersionUID in the transmitted byte stream with the serialVersionUID of the corresponding local entity class. If they are the same, they are considered to be consistent and can be deserialized. Otherwise, an exception of inconsistent serialization version will occur. (InvalidCastException)

Person class

import java.io.Serializable;

/**
 * Person The following requirements must be met before serialization
 * 1.Interface to be implemented: Serializable
 * 2.The current class provides a global constant: serialVersionUID
 * 3.Except that the current Person class needs to implement the Serializable interface, it must also ensure all its internal properties
 *   Must also be serializable. (by default, basic data types are serializable)
 *
 *
 * Supplement: ObjectOutputStream and ObjectInputStream cannot serialize member variables decorated with static and transient
 */
public class Person implements Serializable {
    public static final long serialVersionUID = 475463534532L;

    private String name;
    private int age;
    private int id;

    public Person() {
    }

    public Person(String name, int age, int id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }
}

Test class

import org.junit.Test;

import java.io.*;

/**
 * Use of object streams
 * 1.ObjectInputStream And ObjectOutputStream
 * 2.Function: a processing stream used to store and read basic data type data or objects. Its strength is that it can write objects in Java to the data source and restore objects from the data source.
 *
 * 3.If you want a Java object to be serializable, you need to meet the corresponding requirements. See person java
 *
 * 4.Serialization mechanism:
 * The object serialization mechanism allows Java objects in memory to be converted into platform independent binary streams, which allows this
 * The binary stream is persisted on disk or transmitted to another network node through the network.
 * When other programs get this binary stream, they can restore it to the original Java object.
 *
 */
public class ObjectTest {

    /**
     * Serialization process: save java objects in memory to disk or transfer them over the network
     * Implementation using ObjectOutputStream
     */
    @Test
    public void test(){
        ObjectOutputStream oos = null;
        try {
            //Creative flow
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
            //Manufacturing object
            oos.writeObject(new String("Welcome to Qinshihuang Mausoleum"));
            //Refresh operation
            oos.flush();

            oos.writeObject(new Person("Li Shizhen",65,0));
            oos.flush();


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(oos != null){
                //3. Close the flow
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Deserialization: restore the object in the disk file to a java object in memory
     * Using ObjectInputStream to implement
     */
    @Test
    public void test2(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("object.dat"));

            Object obj = ois.readObject();
            String str = (String) obj;

            Person p = (Person) ois.readObject();

            System.out.println(str);
            System.out.println(p);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

9.5 other serializable requirements

Person class

import java.io.Serializable;

/**
 * Person The following requirements must be met before serialization
 * 1.Interface to be implemented: Serializable
 * 2.The current class provides a global constant: serialVersionUID
 * 3.Except that the current Person class needs to implement the Serializable interface, it must also ensure all its internal properties
 *   Must also be serializable. (by default, basic data types are serializable)
 *
 *
 * Supplement: ObjectOutputStream and ObjectInputStream cannot serialize member variables decorated with static and transient
 *
 */
public class Person implements Serializable{

    public static final long serialVersionUID = 475463534532L;

    private String name;
    private int age;
    private int id;
    private Account acct;

    public Person(String name, int age, int id) {
        this.name = name;
        this.age = age;
        this.id = id;
    }

    public Person(String name, int age, int id, Account acct) {
        this.name = name;
        this.age = age;
        this.id = id;
        this.acct = acct;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                ", acct=" + acct +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }

    public Person(String name, int age) {

        this.name = name;
        this.age = age;
    }

    public Person() {

    }
}

class Account implements Serializable{
    public static final long serialVersionUID = 4754534532L;
    private double balance;

    @Override
    public String toString() {
        return "Account{" +
                "balance=" + balance +
                '}';
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public Account(double balance) {

        this.balance = balance;
    }
}

Test class

import org.junit.Test;

import java.io.*;

/**
 * Use of object streams
 * 1.ObjectInputStream And ObjectOutputStream
 * 2.Function: a processing stream used to store and read basic data type data or objects. Its strength is that it can write objects in Java to the data source and restore objects from the data source.
 *
 * 3.If you want a Java object to be serializable, you need to meet the corresponding requirements. See person java
 *
 * 4.Serialization mechanism:
 * The object serialization mechanism allows Java objects in memory to be converted into platform independent binary streams, which allows this
 * The binary stream is persisted on disk or transmitted to another network node through the network.
 * When other programs get this binary stream, they can restore it to the original Java object.
 */
public class ObjectTest {

    /**
     * Serialization process: save java objects in memory to disk or transfer them over the network
     * Implementation using ObjectOutputStream
     */
    @Test
    public void test(){
        ObjectOutputStream oos = null;
        try {
            //Creative flow
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
            //Manufacturing object
            oos.writeObject(new String("Welcome to Qinshihuang Mausoleum"));
            //Refresh operation
            oos.flush();

            oos.writeObject(new Person("Li Shizhen",65));
            oos.flush();

            oos.writeObject(new Person("placed under house arrest",23,1001,new Account(5000)));
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(oos != null){
                //3. Close the flow
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Deserialization: restore the object in the disk file to a java object in memory
     * Using ObjectInputStream to implement
     */
    @Test
    public void test2(){
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("object.dat"));

            Object obj = ois.readObject();
            String str = (String) obj;

            Person p = (Person) ois.readObject();

            System.out.println(str);
            System.out.println(p);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if(ois != null){
                try {
                    ois.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

10. Random access file stream

  • RandomAccessFile is declared in Java IO package, but directly inherited from Java Lang.Object class. And it implements DataInput and DataOutput interfaces, which means that this class can read and write.
  • RandomAccessFile class supports "random access". The program can directly jump to any place of the file to read and write the file
    • Only part of the contents of the file can be accessed
    • You can append content to an existing file
  • The RandomAccessFile object contains a record pointer to indicate the location of the current read / write location. RandomAccessFile class object can move the record pointer freely:
    • long getFilePointer(): get the current position of the file record pointer
    • void seek(long pos): position the file record pointer to the pos position
  • constructor
    • public RandomAccessFile(Filefile, Stringmode)
    • public RandomAccessFile(Stringname, Stringmode)
  • To create an instance of RandomAccessFile class, you need to specify a mode parameter, which specifies the access mode of RandomAccessFile:
    • r: Open as read-only
    • rw: open for reading and writing
    • rwd: open for reading and writing; Synchronize file content updates
    • rws: open for reading and writing; Synchronize file content and metadata updates
  • If the mode is read-only r. Instead of creating a file, an existing file will be read. If the read file does not exist, an exception will occur. If the mode is rw read / write. If the file does not exist, it will be created. If it does exist, it will not be created.

10.1. RandomAccessFile realizes data reading and writing

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * RandomAccessFile Use of
 * 1.RandomAccessFile Directly inherited from Java Lang. object class, which implements DataInput and DataOutput interfaces
 * 2.RandomAccessFile It can be used as both an input stream and an output stream
 * 3.If RandomAccessFile is used as the output stream, if the file written out does not exist, it will be automatically created during execution.
 *   If the file written out exists, the contents of the original file will be overwritten. (by default, overwrite from scratch)
 */
public class RandomAccessFileTest {

    @Test
    public void test(){

        RandomAccessFile raf1 = null;
        RandomAccessFile raf2 = null;
        try {
            raf1 = new RandomAccessFile(new File("Love and friendship.jpg"),"r");
            raf2 = new RandomAccessFile(new File("Love and friendship 1.jpg"),"rw");

            byte[] buffer = new byte[1024];
            int len;
            while((len = raf1.read(buffer)) != -1){
                raf2.write(buffer,0,len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(raf1 != null){
                try {
                    raf1.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if(raf2 != null){
                try {
                    raf2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    @Test
    public void test2() throws IOException {

        RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");

        raf1.write("xyz".getBytes());

        raf1.close();

    }

}

10.2. RandomAccessFile implements data insertion

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * RandomAccessFile Use of
 * 1.RandomAccessFile Directly inherited from Java Lang. object class, which implements DataInput and DataOutput interfaces
 * 2.RandomAccessFile It can be used as both an input stream and an output stream
 * 3.If RandomAccessFile is used as the output stream, if the file written out does not exist, it will be automatically created during execution.
 *   If the file written out exists, the contents of the original file will be overwritten. (by default, overwrite from scratch)
 *
 * 4.You can "insert" data into RandomAccessFile through related operations
 */
public class RandomAccessFileTest {

    /**
     * Use RandomAccessFile to achieve data insertion effect
     */
    @Test
    public void test3() throws IOException {
        RandomAccessFile raf1 = new RandomAccessFile("hello.txt","rw");

        raf1.seek(3);//Adjust the pointer to the position marked 3
        //Save all data after pointer 3 to StringBuilder
        StringBuilder builder = new StringBuilder((int) new File("hello.txt").length());
        byte[] buffer = new byte[20];
        int len;
        while((len = raf1.read(buffer)) != -1){
            builder.append(new String(buffer,0,len)) ;
        }
        //Call back the pointer and write "xyz"
        raf1.seek(3);
        raf1.write("xyz".getBytes());

        //Writes data from StringBuilder to a file
        raf1.write(builder.toString().getBytes());

        raf1.close();

        //Think: replace StringBuilder with ByteArrayOutputStream
    }

}

11,NIO.2. Use of Path, Paths and Files classes

  • Java NIO (New IO, non blocking IO) is a new set of IO API introduced from Java version 1.4, which can replace the standard Java IO API. NIO has the same function and purpose as the original IO, but it is used in a completely different way. NIO supports buffer oriented (IO is stream oriented) and channel based IO operations. NIO will read and write files in a more efficient way.

  • Java API provides two sets of NIO, one for standard input and output NIO and the other for network programming NIO.

|-----java.nio.channels.Channel
	|-----FileChannel:Process local files
	|-----SocketChannel: TCP Network programming client Channel
	|-----ServerSocketChannel:TCP Server side of network programming Channel
	|-----DatagramChannel: UDP Of sender and receiver in network programming Channel
  • With the release of JDK 7, Java has greatly extended NIO and enhanced its support for file processing and file system features, so that we call them NIO 2. NIO has become an increasingly important part of file processing because of some functions provided by NIO.
  • Early Java only provided a File class to access the File system, but the function of the File class is relatively limited and the performance of the methods provided is not high. Moreover, most methods only return failure when there is an error and do not provide exception information.
  • NIO. In order to make up for this deficiency, the path interface is introduced to represent a platform independent path and describe the location of files in the directory structure. Path can be regarded as an upgraded version of the File class, and the actually referenced resources may not exist.
    • In the past, IO operations were written like this:
import java.io.File;

File file = new File("index.html");

But in Java 7, we can write this:

import java.nio.file.Path;
import java.nio.file.Paths;
Path path = Paths.get("index.html");
  • Meanwhile, NiO 2 in Java nio. Files and paths tool classes are also provided under the file package. Files contains a large number of static tool methods to operate files; Paths contains two static factory methods that return Path.
  • The static get() method provided by the Paths class is used to obtain the Path object:
    • static Pathget(String first, String... more): used to string multiple characters into a path
    • Static Path get (uri): returns the Path corresponding to the specified uri

Path interface

Files class

Topics: Java