IO stream in Java

Posted by clandestine555 on Tue, 01 Feb 2022 04:06:42 +0100

The following are my notes on watching the Java learning video of shangsilicon valley

Use of File class

  • java.io.File class: the 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

File class common constructor

  • public File(String pathname)
    Create a File object with pathname as the path, which can be an absolute path or a relative path. If pathname is a relative path, the default current path is in the system attribute user Stored in dir
    • The drive letter is a fixed path
    • Relative path: it starts from a certain position
  • public File(String parent, String child)
    Create a File object with parent as the parent path and child as the child path
  • public File(File parent, String child)
    Create a File object based on a parent File object and a child File path

path separator

Each level of directories in the path is separated by a path separator.

The path separator is system dependent:

  • windows and DOS systems use "\" by default (it is often written as "\ \" because of escape characters)
  • UNIX and URL s are represented by "/"

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. Provide separators dynamically according to the operating system.

give an example:

File file1 = new File( "d:\\atguigu\\info.txt");
File file2 = new File("d:" + File.separator + "atguigu" + File.separator + "info.txt");
File file3 = new File( "d:/atguigu");

Common methods of File class

Get function of File class:

  • 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. null if none
  • public long length(): get the length of the file (i.e. the number of bytes). Cannot get the length of the directory
  • public long lastModified(): gets the last modification time, in milliseconds
  • public String[] list(): get 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

Rename function of File class

  • public boolean renameTo(File dest): rename the file to the specified file path
    If you call file1 Rename (file2). To return true, file1 must exist in the hard disk and file2 must not exist in the hard disk

Judgment function of File class

  • 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

Creation function of File class

  • public boolean createNewFile(): creates a file. If the file exists, it will not be created and false will be returned
  • public boolean mkdir(): create 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 the upper file directory does not exist, create it together

Note: if you create a file or the file directory does not have a write letter path, it is under the project path by default

Delete function of File class

  • public boolean delete(): deletes files or folders

Precautions for deletion:
Deletion in Java does not go to the recycle bin
To delete a file directory, please note that the file directory cannot contain files or file directories

 

IO stream principle and stream classification

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

In Java program, the input / output operation of data is carried out in the way 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

Classification of flow

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

Flow architecture

Abstract base classNode stream (file stream)Buffer stream (a kind of processing stream)
InputStreamFileInputStream
(read(byte[] buffer))
BufferedInputStream
(read(byte[] buffer))
OutputStreamFileOutputStream
(write(byte[] buffer,0,len))
BufferOutputStream
(write(byte[] buffer,0,len))/ flush()
ReaderFileReader
(read(char[] cbuf))
BufferedReader
(read(char[] cbuf) / readLine())
WriterFileWriter
(write(char[] cbuf,0,len))
BufferedWriter
(write(char[] cbuf,0,len))/ flush()

 

Node stream (or file stream)

For text files (such as. TXT,. Java,. C,. CPP), use character stream processing
For non text files (such as. JPG,. MP3,. MP4,. Avi,. Doc,. Ppt), use byte stream processing

Character stream

Note that character stream cannot be used to process non text file data such as pictures, but character stream should be used to process text files

Basic operation of reading data by FileReader

Example: put the hello. In the current Module directory Txt file content is read into the program and output to the console
Description:
1. Exception handling: in order to ensure that the stream resources can be closed, try catch finally is required
2. The read in file must exist, otherwise FileNotFoundException will be reported

Using read():
read(): returns a character read in. If the end of the file is reached, - 1 is returned

import org.junit.Test;

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

public class Sample {
    @Test
    public void testFileReader() {
        FileReader fr = null;
        try {
            //1. Instantiate the object of File class to indicate the File to be operated
            File file = new File("hello.txt");//The file path under Test is compared with the current Module, while in the main function, it is compared with the current project
            //2. Provide specific flow
            fr = new FileReader(file);
            //3. Data reading
            //read(): returns a character read in. If the end of the file is reached, - 1 is returned
            //Mode 1:
//            int data = fr.read();
//            while (data != -1) {
//                System.out.print((char) data);
//                data = fr.read();
//            }
            //Method 2: grammatical modification of method 1
            int data;
            while ((data = fr.read()) != -1) {
                System.out.print((char) data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. Close the flow
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Use read(char[] cbuf):
read(char[] cbuf): returns the number of characters read into the cbuf array each time. If it reaches the end of the file, it returns - 1

import org.junit.Test;

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

public class Sample {
    @Test
    public void testFileReader() {
        FileReader fr = null;
        try {
            //1. Instantiate the object of File class to indicate the File to be operated
            File file = new File("hello.txt");//The file path under Test is compared with the current Module, while in the main function, it is compared with the current project
            //2. Provide specific flow
            fr = new FileReader(file);
            //3. Data reading
            //read(char[] cbuf): returns the number of characters read into the cbuf array each time. If it reaches the end of the file, it returns - 1
            char[] cbuf = new char[5];
            int len;
            while ((len = fr.read(cbuf)) != -1) {
                //Mode 1:
                //Wrong writing: because the old data at the end of the character array that has not been overwritten after the last assignment may be output
//                for (char c : cbuf) {
//                    System.out.print(c);
//                }
                //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 s = new String(cbuf);
//                System.out.print(s);
                //Correct writing:
                String s = new String(cbuf, 0, len);
                System.out.print(s);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4. Close the flow
            if (fr != null) {
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

FileWriter writes out the basic operation of data

  1. For output operation, the corresponding File may not exist and no exception will be reported
  2. If the File in the hard disk corresponding to File does not exist, this File will be automatically created during output
    If the File in the hard disk corresponding to File 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 to the original file
import org.junit.Test;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

public class Sample {
    @Test
    public void testFileReader() {
        FileWriter fw = null;
        try {
            //1. Provide the object of File class to indicate the File to be written out
            File file = new File("hello.txt");
            //2. Provide the object of FileWriter for writing out data
            fw = new FileWriter(file);
            //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();
                }
            }
        }
    }
}

Byte stream

When using byte stream to process text files, there may be garbled code. It is better to use character stream
However, if you only copy text files, you can use byte stream (but note that you can't use character stream to copy non text files)

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 Sample {
    @Test
    public void testFileReader() {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            //1. Instantiate the object of File class to indicate the File to be operated
            File srcFile = new File("Original picture.jpg");
            File destFile = new File("Copy file.jpg");
            //2. Provide specific flow
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(destFile);
            //3. Data reading
            byte[] buffer = new byte[5];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                //4. Close resources
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (fis != null) {
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

 

Buffer stream

Buffer stream:
BufferedInputStream
BufferedOutputStream
BufferedReader
BufferedWriter

Function of buffer stream: improve the reading and writing speed of stream
Reason for improving read and write speed: a buffer is provided internally
You can explicitly call the flush method to flush the buffer, but you generally don't need to write explicitly in the buffer stream, because the flush method will be called automatically when the buffer is full in the buffer stream

Processing stream is to "socket" the existing stream to transform the original stream (just like buffering stream is to improve the performance)

Using BufferedInputStream and BufferedOutputStream

import org.junit.Test;

import java.io.*;

public class Sample {
    @Test
    public void testFileReader() {
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            //1. Documentation
            File srcFile = new File("source file.jpg");
            File destFile = new File("Copy file.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);
            }
        } 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 closing the outer layer flow, the inner layer flow will also be closed automatically. In fact, we can omit the closing of the inner layer flow
//          fos.close();
//          fis.close();
        }
    }
}

Using BufferedReader and BufferedWriter

import org.junit.Test;

import java.io.*;

public class Sample {
    @Test
    public void testFileReader() {
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            //Create files and corresponding streams
            br = new BufferedReader(new FileReader(new File("Original document.txt")));
            bw = new BufferedWriter(new FileWriter(new File("Copy file.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();// It can also be ignored and no explicit call is made
//            }
            //Method 2: use String
            String data;
            while ((data = br.readLine()) != null) {
                //data does not contain newline
                //Mode 1:
                //bw.write(data+"\n");
                //Mode 2:
                bw.write(data);
                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();
                }
            }
        }
    }
}

 

Conversion flow

  • Conversion stream provides conversion between byte stream and character stream, which belongs to character stream (rule: class name ends with Reader and Writer)
  • The Java API provides two transformation streams:
    • InputStreamReader: convert InputStream to Reader (convert byte input stream to character input stream)
    • OutputStreamWriter: convert Writer to OutputStream (convert character output stream to byte output stream)
  • 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 and realize the functions of encoding and decoding
    • Decoding: byte, byte array → character array, string
    • Encoding: character array, string → byte, byte array

Supplementary: character set

  • 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 characters of each country are represented by numbers and correspond one by one to form a table - this is the coding table
  • Common coding tables:
    • ASCII: American standard information interchange code, which can be represented by 7 bits of one byte
    • ISO8859-1: Latin code table and European code table are represented by 8 bits of one 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, with a maximum of two byte coding
    • 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. One character can be represented by 1 ~ 4 bytes

Unicode is not perfect. Here are three problems. One is that we already know that only one byte is enough for English letters. The second problem is how to distinguish Unicode from ASCII? How does the computer know that two bytes represent one symbol instead of two symbols respectively? Third, if the encoding method is the same as that of GBK and other double bytes, and the highest bit is 1 or O 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 is to transmit data 8 bits at a time, while UTF-16 is to transmit 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 coding scheme. The recommended Unicode encodings are UTF-8 and UTF-16.

Use of InputStreamReader

import org.junit.Test;

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

public class Sample {
    @Test
    public void testFileReader() throws IOException {
        //Try catch finally is not written here to save trouble. It should be written
        FileInputStream fis = new FileInputStream("Original document.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 character set used when saving the file
        InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
        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();
    }
}

Use of OutputStreamWriter

import org.junit.Test;

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

public class Sample {
    @Test
    public void testFileReader() throws IOException {
        //Try catch finally is not written here to save trouble. It should be written
        //1. Document making and flow making
        FileInputStream fis = new FileInputStream("Original document.txt");
        FileInputStream fos = new FileInputStream("Copy file.txt");

        InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
        OutputStreamWriter osw = new OutputStreamWriter("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();
    }
}

 

Standard input and output streams (understand)

  • 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
  • Redirection: change the default device through the setIn and setOut methods of the System class.
    • public static void setIn(InputStream in)
    • public static void setOut(PrintStream out)

Example: when inputting a string from the keyboard, it is required to convert the read whole line of string into uppercase output, and then continue the operation until "e" or "exit" is input, and then exit the program

Method 1: use the Scanner implementation and call next() to return a string
Method 2: use system In implementation, system In → conversion flow → BufferedReader's readLine()

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

public class Sample {
    public static void main(String[] args) {
        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(data.equalsIgnoreCase("e")||data.equalsIgnoreCase("exit")){
                if ("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)) {//This is better than the above
                    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();
                }
            }
        }
    }
}

 

Print stream (understand)

  • Realize the conversion of the data format of the basic data type into 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 loxeception exception
    • 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

 

Data flow (understanding)

  • In order to easily operate 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)
    • DatalnputStream and DataOutputStream
    • "Socket" on the streams of subclasses InputStream and OutputStream respectively
  • Methods in DatalnputStream
    • boolean readBoolean()
    • byte readByte()
    • char readChar()
    • float readFloat()
    • double readDouble()
    • short readShort()
    • long readLong()
    • int readInt()
    • String readUTF()
    • void readFully(byte[] b)
  • Methods in DataOutputStream
    • Change the read of the above method to the corresponding write

write in:

import java.io.DataOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class Sample {
    public static void main(String[] args) throws IOException {
        //To handle exceptions, you should still use try catch finally
        DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt"));

        dos.writeUTF("Lau Andy");
        dos.flush();//Refresh operation to write the data in memory to the file
        dos.writeInt(23);
        dos.flush();
        dos.writeBoolean(true);
        dos.flush();

        dos.close();
    }
}

Read: note that the order of reading different types of data should be consistent with the order of saving data when writing the file, otherwise an exception will be reported

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Sample {
    public static void main(String[] args) throws IOException {
        //To handle exceptions, you should still use try catch finally
        DataInputStream dis = new DataInputStream(new FileInputStream("data.txt"));

        String name = dis.readUTF();
        int age = dis.readInt();
        boolean isMale = dis.readBoolean();

        dis.close();
    }
}

 

Object flow

  • 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 saving basic type data or objects with ObjectOutputStream class (converting a java object in memory to an object in disk file)
  • Deserialization: a mechanism for reading basic type data or objects with ObjectlnputStream class (restoring an object in disk file to a java object in memory)
  • ObjectOutputStream and ObjectInputStream cannot serialize static and transient decorated member variables

object serialization

  • The object serialization mechanism allows Java objects in memory to be converted into platform independent binary streams (serialization), 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 (deserialization)
  • 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) process, and RMI is the basis of Java EE. Therefore, serialization mechanism is the foundation of Java EE platform
  • If you need to make an object support serialization mechanism, you must make the class to which the object belongs and its properties serializable. In order to make a class serializable, the class must implement one of the following two interfaces. Otherwise, a NotSerializableException is thrown
    • Serializable (this is an identification interface, because the interface has no methods to implement)
    • Externalizable
  • 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 the 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 during deserialization.
    • If the class does not show the definition of this static variable, 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 entity class. If they are the same, they are considered to be consistent and can be deserialized. Otherwise, the exception of inconsistent serialization version will appear. (InvalidCastException)

Serialization process: implemented using ObjectOutPutStream

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Sample {
    public static void main(String[] args) {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
            oos.writeObject(new String("I Love Beijing Tiananmen "));
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Deserialization process: implemented using ObjectlnputStream

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class Sample {
    public static void main(String[] args) {
        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();
                }
            }
        }
    }
}

Custom classes implement serialization and deserialization

To make a java object serializable, you need to meet the following requirements:
1. Interface to be implemented: Serializable
2. The current class needs to provide a global constant: serialVersionUID
3. All internal attributes can be serialized (by default, the basic data type can be serialized)

Example: make the Person class serializable

class Person implements Serializable {
    public static final long serialVersionUID = 475463534532L;//This value can be taken at will
    private String name;
    public Person(String name) {
        this.name = name;
    }
}

 

Random access file stream

  • RandomAccessFile is declared in Java IO package, but directly inherited from Java Lang.Object class. And it implements Datalnput and DataOutput interfaces, which means that this class can read and write, and can be used as input stream and output stream.
  • RandomAccessFile class supports "random access". The program can directly jump to any place of the file to read and write the file
    • Only partial 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): locate the file record pointer to the pos position
  • Constructor:
    • public RandomAccessFile(File file, String mode)
    • public RandomAccessFile(String name, String mode)
  • To create an instance of RandomAccessFile class, you need to specify a mode parameter, which refers to
    Set 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, the file will not be created, but an existing file will be read. If the read file does not exist, an exception will appear
  • If the mode is rw read / write and RandomAccessFile is used as the output stream:
    • If the file written out does not exist, it is automatically created during execution
    • If the file written out exists, the contents of the original file will be overwritten. (by default, overwrite from scratch)
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

public class Sample {
    public static void main(String[] args) {
        RandomAccessFile raf1 = null;
        RandomAccessFile raf2 = null;
        try {
            raf1 = new RandomAccessFile(new File("picture.jpg"), "r");
            raf2 = new RandomAccessFile(new File("picture.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 (raf1 != null) {
                try {
                    raf2.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

When RandomAccessFile is used as the output stream, it is overwritten from scratch by default. Note the following situations

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

public class Sample {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf1 = new RandomAccessFile("hello.txt", "rw");
        raf1.write("abcdefg".getBytes());
        raf1.write("xyz".getBytes());
        raf1.close();
        //Get hello Txt content is abcdefgxyz
    }
}
import java.io.IOException;
import java.io.RandomAccessFile;

public class Sample {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf1 = new RandomAccessFile("hello.txt", "rw");
        RandomAccessFile raf2 = new RandomAccessFile("hello.txt", "rw");
        raf1.write("abcdefg".getBytes());
        raf2.write("xyz".getBytes());
        raf1.close();
        raf2.close();
        //Get hello Txt is xyzdefg
    }
}

RandomAccessFile is used to realize the effect of data insertion

Example: insert xyz after abc

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

public class Sample {
    public static void main(String[] args) throws IOException {
        RandomAccessFile raf1 = new RandomAccessFile("hello.txt", "rw");
        RandomAccessFile raf2 = new RandomAccessFile("hello.txt", "rw");
        raf1.write("abcdefg".getBytes());
        raf2.seek(3);//Adjust the pointer to the position marked with angle 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 = raf2.read(buffer)) != -1) {
            builder.append(new String(buffer, 0, len));
        }
        raf2.seek(3);//Turn the pointer back to the position marked 3
        raf2.write("xyz".getBytes());
        //Write data from StringBuilder to file
        raf2.write(builder.toString().getBytes());
        raf1.close();
        raf2.close();
        //Get hello Txt content is abcxyzdefg
    }
}

We can use RandomAccessFile to realize a multi-threaded breakpoint download function. Friends who have used the download tool know that two temporary files will be created before downloading, one is an empty file with the same size as the downloaded file, and the other is a file that records the location of the file pointer. Each time we pause, the last pointer will be saved, Then, when the breakpoint is downloaded, it will continue to download from the last place, so as to realize the function of breakpoint download or upload.

 

NIO.2. Use of Path, Paths and File classes (understand)

Java NIO overview

  • Java NIO (New lO, non blocking LO) 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: the Channel of the TCP network programming client
    Serversocketchannel: the server-side Channel of TCP network programming
     ----- datagramchannel: the Channel of the sender and receiver in UDP network programming

NIO.2

With the release of JDK7, 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.

Path, Paths, and Files core API s

  • Early Java only provided a File class to access the File system, but the function of File class is relatively limited and the performance of the method 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, which represents a platform independent path and describes 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 Path get(String first, String... more): used to string multiple characters into a path
    • static Path get(URl uri): returns the Path corresponding to the specified uri

Topics: Java Back-end