Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

1, the use of File class

Java.io.File class: Abstract representation of files and File directory paths, platform-independent.

File can create, delete, and rename files and directories, but File cannot access the File itself. If you need access to the file content itself, you need to use an input/output stream.

To represent a real File or directory in a Java program, you must have 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 an argument to the flow’s constructor.

1.1. File common constructor

1, Public File(String pathName)

  • Create a File object with pathname as the path. It can be an absolute path or a relative path. If pathName is a relative path, the default current path is stored in the system property user.dir.

  • Absolute path: a fixed path, starting from the drive letter

  • Relative path: Starts relative to a location

Example code:

/ / instantiate
File file = new File("hello.txt");// Relative path
// Use \\ to avoid being considered an escape character in Java
File file1 = new File("E:\\JavaSE\\Commonly used classes \\ SRC \\ IO \hi.txt");// Absolute path

// File is only a memory level object, there is no real File or directory on the hard disk.
System.out.println(file);//hello.txt
System.out.println(file1);//E: JavaSE/Commonly used class SRC/IO/hi.txt
Copy the code

Public File(String parent,String child)

  • Create File object with parent as parent path and child as child path.

Example code:

// Instantiate a file directory named "Commonly" in the directory "E:\\JavaSE\\Commonly Used classes"
File file2 = new File(E:\\JavaSE\\Commonly Used Classes."Commonly");

System.out.println(file2);//E:\JavaSE\Commonly used
Copy the code

3, public File(File parent,String child)

  • Creates a File object based on a parent File object and a child File path

Example code:

// Instantiate a file named "hello.txt" in the "E:\JavaSE\Commonly Used classes \ "directory
File file4 = new File(file2,"hello.txt");
// Instantiate a file directory named "hello" in the "E: JavaSE Commonly Used classes "directory
File file5 = new File(file2,"hello");

System.out.println(file4);//E:\JavaSE\Commonly used \ hell.txt
System.out.println(file5);//E:\JavaSE\Commonly used \hello
Copy the code

1.2. Path separators

Directories at each level of a path are separated by a path separator.

Path separators are system specific:

  • The default for Windows and DOS systems is “\”
  • UNIX and urls are represented by a slash

Java programs can run across platforms, so use path separators with caution. Use \\ to avoid being considered an escape character in Java.

To solve this problem, the File class provides a constant: public static Final String separator.

Depending on the operating system, delimiters are provided dynamically. For example:

File file2 = new File("d:" + File.separator + "hello” + File.separator + "info.txt");
Copy the code

1.3 common methods of File

Access to the File class

Public String getAbsolutePath() : Obtains the absolute path

Public String getPath() : Obtain path

Public String getName() : Gets the name

Public String getParent() : Gets the path of the upper-layer file directory. If no, null is returned

Public Long Length () : Gets the file length(that is, bytes). Cannot get directory length

Public long lastModified() : gets the lastModified time, in milliseconds

Test code:

File file1 = new File("hello.md");
File file2 = new File("D:\\io\\hi.md");

System.out.println(file1.getAbsoluteFile());// Get the absolute path
System.out.println(file1.getPath());// Get the path
System.out.println(file1.getName());// Get the name
System.out.println(file1.getParent());// Get the upper file directory path. If no, null is returned
System.out.println(file1.length());// Get the file length (that is, bytes). Cannot get directory length
System.out.println(file1.lastModified());// Get the last modification time, millisecond value

System.out.println();

System.out.println(file2.getAbsoluteFile());// Get the absolute path
System.out.println(file2.getPath());// Get the path
System.out.println(file2.getName());// Get the name
System.out.println(file2.getParent());// Get the upper file directory path. If no, null is returned
System.out.println(file2.length());// Get the file length (that is, bytes). Cannot get directory length
System.out.println(file2.lastModified());// Get the last modification time, millisecond value
Copy the code

Public String[]list() : Gets all files in a specified directory or an array of file directory names

Public File[] listFiles() : Gets all files in a specified directory or an array of files in a specified directory

Test code:

// The file directory must exist
File file = new File("E:\\Redis");
String[] list = file.list();// Get all files in the specified directory or an array of file directory names
for (String s : list){
    System.out.println(s);
}
System.out.println();
File[] files = file.listFiles();// Get all files in the specified directory or an array of files in the specified directory
for (File f : files){
    System.out.println(f);
}
Copy the code

Renaming of the File class

Public Boolean renameTo(File dest) : Renames the File to the specified File path

Test code:

File file = new File("hello.md");
File file1 = new File("D:\\io\\hello1.md");
// Requirements: File exists in the hard disk, file1 does not exist in the hard disk, after renameTo, the original file file is transferred to the file1 path
boolean b = file.renameTo(file1);// Rename the file to the specified file path
System.out.println(b);
Copy the code

File class judgment function

Public Boolean isDirectory() : Check whether it is a file directory

Public Boolean isFile() : Checks whether it is a file

Public Boolean exists() : Checks whether it exists

Public Boolean canRead() : Checks whether it is readable

Public Boolean canWrite() : Checks whether it can be written

Public Boolean isHidden() : Indicates whether to hide

Test code:

File file = new File("hello.md");
File file1 = new File("D:\\io");

System.out.println(file.isDirectory());// Check whether it is a file directory false
System.out.println(file1.isDirectory());// Check whether it is a file directory true

System.out.println(file.isFile());// Check whether it is a file directory true
System.out.println(file1.isFile());// Check whether it is a file directory false

System.out.println(file.exists());// Check whether true exists
System.out.println(file1.exists());// Check whether true exists

System.out.println(file.canRead());// Check whether it is readable true

System.out.println(file.canWrite());// Check whether you can write true

System.out.println(file.isHidden());// Determine whether to hide false
Copy the code

File class creation and deletion

Public Boolean createNewFile() : Create a file. If the file exists, it is not created and false is returned

Public Boolean mkdir() : Creates a file directory. If the file directory exists, it is not created. If an upper directory for this file directory does not exist, it is not created

Public Boolean mkdirs() : Creates a file directory. If the upper-layer file directory does not exist, create it

Note: If you create a file or the file directory does not write a drive path, the default is in the project path

Public Boolean delete() : Deletes a file or folder

Note: Deletes in Java do not go to the recycle bin.

To delete a file directory, note that the file directory cannot contain files or file directories.

Test code:

// Create and delete files
File file = new File("hello.txt");

if(! file.exists()){ file.createNewFile(); System.out.println("Created successfully");
}else {
    file.delete();
    System.out.println("Deleted successfully");
}

// Create and delete files and directories
File file1 = new File("D:\\io\\io1");
boolean mkdir = file1.mkdir();
if (mkdir){
    System.out.println("Created successfully 1");
}else {
    file1.delete();
    System.out.println("Deleted successfully 1");
}

File file2 = new File("D:\\io2\\io3");
boolean mkdir2 = file2.mkdirs();
if (mkdir2){
    System.out.println("Created successfully 2");
}else {
    file2.delete();
    System.out.println("Deleted successfully 2");
}
Copy the code

2. IO flow principle and flow classification

2.1 IO flow principle

I/O stands for Input/Output. I/O is a very practical technique for handling data transfer between devices. Such as reading/writing documents, network communication, etc.

  • Input: Reads external data (disk, CD, and other storage device data) into the program (memory).
  • Output: Outputs program (memory) data to storage devices such as disks and CD-RoMs.

In Java programs, data input/output operations take the form of a stream.

The java.io package provides a variety of “stream” classes and interfaces to retrieve different kinds of data and input or output data through standard methods.

2.2. Classification of streams

According to the different operation data units: byte stream (8 bit), character stream (16 bit)

According to the different flow direction of data flow, it can be divided into input flow and output flow

According to the different roles of streams, they are divided into node flows and processing flows

3. IO stream architecture

1. Java IO streams involve more than 40 classes, which are actually very regular and derived from the following four abstract base classes.

Abstract base class Byte streams (non-text files such as video, music…) Character stream (text file)
The input stream InputStream Reader
The output stream OutputStream Writer

2. All subclass names derived from these four classes are suffixed with the name of their parent class.

IO flow system

4. Node flow

4.1 Operation of FileReader to read data

Read the contents of the file into the program and print it on the console.

Use the read() method

@Test
public void test1(a){
    FileReader reader = null;
    try {
        // Instantiate the File object, specifying the File to operate on
        File file = new File("hello.txt");
        // Create a concrete stream
        reader = new FileReader(file);
        // Data is read in. Read () : Returns a character read in, or -1 if it reaches the end of the file
        int i;
        while((i = reader.read()) ! = -1){
            System.out.print((char)i);//helloworld}}catch (IOException e) {
        e.printStackTrace();
    } finally {
        / / close the flow
        try {
            if(reader ! =null)
            reader.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

Overloading methods with read() : read(char[] cbuf)

    @Test
    public void test2(a) {

        FileReader fileReader = null;
        try {
            // Instantiate the File object, specifying the File to operate on
            File file = new File("hello.txt");

            // Create a concrete stream
            fileReader = new FileReader(file);

            char[] chars = new char[5];
            int len;
            Read (char[] cbuf) : read(char[] cbuf) : read(char[] cbuf) : read(char[] cbuf) : read(char[] cbuf) : read(char[] cbuf
            while((len = fileReader.read(chars)) ! = -1) {/ / way
// for (int i = 0; i < len; i++) {
// System.out.print(i);
/ /}
                2 / / way
                String str = new String(chars,0,len); System.out.print(str); }}catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fileReader ! =null) {
                try {
                    // Close the resource
                    fileReader.close();
                } catch(IOException e) { e.printStackTrace(); }}}}Copy the code

4.2 FileWriter writes data operations

@Test
public void test3(a){
    FileWriter fileWriter = null;

    try {
        //1. Instantiate the File object to specify the File to be written to
        File file = new File("hello1.txt");

        //2. Create a concrete stream
        fileWriter = new FileWriter(file);

        //3. Write operations
        fileWriter.write("I have a dream\n");
        fileWriter.write("you need to have a dream");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if(fileWriter ! =null)
                //4. Close the resource
            fileWriter.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

Description:

The file corresponding to the write operation may not exist, and no error will be reported.

If the File corresponding to File does not exist on the hard disk, the system automatically creates the File during the write process.

File If the corresponding File exists on the hard disk:

  • If the stream uses a FileWriter(file) or FileWriter(file,false) constructor, the original file is overwritten
  • If the stream uses a FileWriter(file,true) constructor, it does not overwrite the original file, but appends the content to the original file.

4.3 FileReader and FileWriter implement text file copying

Principle: read the contents of a text file into the program (memory), and then write the contents into another text file, so that the text file copy is realized.

@Test
public void test4(a) {
    FileReader fileReader = null;
    FileWriter fileWriter = null;

    try {
        //1. Instantiate the File object to specify which files to read and write
        File oldFile = new File("hello.txt");
        File newFile = new File("hello1.txt");

        //2. Create input streams and output streams
        fileReader = new FileReader(oldFile);
        fileWriter = new FileWriter(newFile);


        char[] cbuf = new char[5];
        int len = 0;
        while((len = fileReader.read(cbuf)) ! = -1){
            fileWriter.write(cbuf,0,len); }}catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if(fileWriter ! =null)
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if(fileReader ! =null)
                fileReader.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

4.4 FileInputStream and FileOutputStream implement copying of non-text files

FileInputStream and FileOutputStream are byte streams. Reading or writing text files using byte streams may cause garbled characters.

@Test
public void test(a) {
    FileInputStream fileInputStream = null;
    FileOutputStream fileOutputStream = null;
    try {
        // Specifies non-text files to read and write
        File srcFile = new File("1.jpg");
        File destFile = new File("2.jpg");

        / / create the stream
        fileInputStream = new FileInputStream(srcFile);
        fileOutputStream = new FileOutputStream(destFile);

        byte[] bytes = new byte[1024];
        int len ;
        // Copy operation
        while((len = fileInputStream.read(bytes)) ! = -1){
            fileOutputStream.write(bytes,0,len); }}catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            // Close the resource
            if(fileInputStream ! =null)
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if(fileOutputStream ! =null)
            fileOutputStream.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

5. Cache streams

Buffering flows are a type of processing flow. Caching streams can greatly improve the efficiency of read and write operations.

5.1 BufferedInputStream and BufferedOutputStream implement non-text file copying

@Test
public void test1(a) {

    BufferedInputStream bis = null;
    BufferedOutputStream bos = null;
    try {
        // Create a file object
        File srcFile = new File("1.jpg");
        File destFile = new File("3.jpg");

        // Build the node flow first
        FileInputStream fis = new FileInputStream(srcFile);
        FileOutputStream fos = new FileOutputStream(destFile);

        // Re-create buffer flow
        bis = new BufferedInputStream(fis);
        bos = new BufferedOutputStream(fos);

        // Copy operation
        byte[] buffer = new byte[1024];
        int len;
        while((len = bis.read(buffer)) ! = -1){
            bos.write(buffer,0,len); }}catch (IOException e) {
        e.printStackTrace();
    } finally {
        1. Shut down the outer layer flow first, and then shut down the inner layer flow. 2
        try {
            if(bos ! =null)
            bos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if(bis ! =null)
            bis.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

5.2 BufferedReader and BufferedWriter implement text file replication

    @Test
    public void test2(a) {
        FileReader fr = null;
        FileWriter fw = null;

        try {
            // Create a file object
            File srcFile = new File("hello.txt");
            File destFile = new File("hello2.txt");

            // Build the node flow first
            fr = new FileReader(srcFile);
            fw = new FileWriter(destFile);

            // Re-create buffer flow
            BufferedReader br = new BufferedReader(fr);
            BufferedWriter bw = new BufferedWriter(fw);

            // Copy operation
            / / way
// char[] buffer = new char[1024];
// int len;
// while((len = br.read(buffer)) ! = 1) {
// bw.write(buffer,0,len);
/ /}
            // readLine() reads one line at a time
            String data;
            while((data = br.readLine()) ! =null){
                bw.write(data);// Data does not contain newlines
                bw.newLine();// Provide line breaks}}catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // Close the resource
                if(fw ! =null)
                fw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fr ! =null)
                fr.close();
            } catch(IOException e) { e.printStackTrace(); }}}Copy the code

5.3 Practice: Count the number of occurrences of each character in the text

@Test
public void test3(a) {
    FileReader fr = null;
    FileWriter fw = null;
    BufferedWriter bw = null;

    try {
        // Create a HashMap where key is the character and value is the number of occurrences of the character
        HashMap<Character, Integer> map = new HashMap<>();
        fr = new FileReader(new File("hello.txt"));

        int c = 0;
        // Read the file into the map
        while((c = fr.read()) ! = -1) {// Convert each character read to char
            char ch = (char) c;
            // If the character does not exist in map
            if ((map.get(ch)) == null) {// Add this character as a key to the map with value 1, since it is the first time it is added
                map.put(ch,1);
            }else {
                // If the character already exists in the map, add +1 to the original value
                map.put(ch,map.get(ch) + 1); }}// Write the map data to count.txt
        fw = new FileWriter(new File("count.txt"));
        // Write out data using the cache stream
        bw = new BufferedWriter(fw);

        / / traverse map
        Set<Map.Entry<Character, Integer>> entrySet = map.entrySet();
        for (Map.Entry<Character, Integer> entry : entrySet){
            switch (entry.getKey()){
                case ' ':
                    bw.write("Space =" +entry.getValue());
                    break;
                case '\t':
                    bw.write("The TAB key =" +entry.getValue());
                    break;
                case '\r':
                    bw.write("Return =" +entry.getValue());
                    break;
                case '\n':
                    bw.write("A newline =" +entry.getValue());
                    break;
                default:
                    bw.write(entry.getKey() + "=" + entry.getValue());
            }
            / / a newlinebw.newLine(); }}catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            // Close the resource
            if(bw ! =null)
                bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if(fr ! =null)
            fr.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

6. Transform the flow

6.1 Overview of transformation flow

A transformation flow is also a type of processing flow.

Conversion streams provide conversion between byte streams and character streams.

The JavaAPI provides two conversion flows:

  • LnputStreamReader: converts InputStream to Reader and byte InputStream to character InputStream
  • OutputStreamWriter: converts Writer to OutputStream, character OutputStream to byte OutputStream

Converting to a character stream is more efficient when the data in the byte stream is all characters.

A lot of times we use conversion streams to deal with file garbled problems. Realize the function of encoding and decoding.

6.2 use of InputStreamReader

LnputStreamReader: converts InputStream to Reader and byte InputStream to character InputStream

@Test
public void test1(a){
    InputStreamReader isr = null;
    try {
        // Create a byte input stream
        FileInputStream fis = new FileInputStream("hello.txt");
        The second parameter specifies the character set to be used according to the character set used when the file was saved. If this parameter is not specified, the default character set will be used
        isr = new InputStreamReader(fis,"utf-8");
        char[] cbuf = new char[1024];
        int len;
        while((len = isr.read(cbuf)) ! = -1){
            String str = new String(cbuf,0,len); System.out.println(str); }}catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            // Close the resource
            if(isr ! =null)
            isr.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

6.3 Conversion stream to achieve text file encoding conversion

@Test
public void test2(a){

    InputStreamReader isr = null;
    OutputStreamWriter osw = null;
    try {
        // The original text File object
        File file = new File("hello.txt");
        // The converted GBK encoded File object
        File file1 = new File("hello_gbk.txt");

        // Create a node flow
        FileInputStream fis = new FileInputStream(file);
        FileOutputStream fos = new FileOutputStream(file1);

        // Create the transformation stream and specify the character set encoding
        isr = new InputStreamReader(fis,"utf-8");
        osw = new OutputStreamWriter(fos,"gbk");

        char[] cbuf = new char[1024];
        int len;
        while((len = isr.read(cbuf)) ! = -1) {
            osw.write(cbuf,0,len); }}catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if(osw ! =null)
            osw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            if(isr ! =null)
            isr.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

View the original text file:

After running, view the converted GBK format text file:

7. Common character encodings

Origin of code table:

Computers can only recognize binary data, and their early origins are electrical signals. In order to facilitate the use of computer, let it recognize the characters of various countries. Will each country’s words with numbers to represent, and one by one correspondence, to form a table. This is the code table.

Common coding tables:

ASCIIl: American standard information exchange code. Can be represented by seven bits of a byte.

ISO8859-1; Latin code watch. European code watch. Represented by 8 bits of a byte.

GB2312; Chinese code table in China. Up to two bytes encode all words bamboo

GBK: The Chinese code table has been upgraded to incorporate more Chinese characters. Two bytes encoding at most

Unicode: International standard code that combines all characters currently in use by humans. Assign a unique character code to each character. All text is represented by two bytes.

Utf-8: Variable length encoding that can represent a character in the range of 1 to 4 bytes.

Unicode is not perfect, and there are three problems:

One is, we already know that the English letter is only a single byte,

The second question is how do you distinguish Unicode from ASCII? How does the computer know that two bytes represent one symbol, rather than two separate symbols?

Third, if the highest bit is 1 or O to represent two bytes and one byte, as with GBK and other double-byte encodings, there are too few values to be used to represent characters, not enough to represent all characters. Unicode was not widely available for a long time, until the advent of the Internet.

A variety of transport-oriented UTF (UCS Transfer Format) standards emerged. As the name implies, 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 code designed for transmission and makes it borderless so that it can display characters from all cultures around the world.

Unicode simply defines a large, universal character set that may assign a unique number to each character, depending on the character encoding scheme. The recommended Unicode encoding is UTF-8 and IUTF-16.

Standard input and output streams

Overview of standard input and output streams

Standard input and output streams are also a type of processing stream.

Systejn.in and System.out represent the System standard input and output devices, respectively.

The default input device is: keyboard, output device is: monitor

System.in is of type InputStream.

System.out is of type PrintStream, which is a subclass of OutputStream, FilterOutputStream

Redirection: Change the default device using the setln, setOut methods of the System class.

public static void setln(InputStream in)

public static void setOut(PrintStream out)

Use of standard input and output streams

Typing a string from the keyboard requires that the entire line of the string read be converted to uppercase output. Continue typing until “e” or “exit” is entered to exit the program.

public class OtherStreamTest {
    public static void main(String[] args) {

        BufferedReader br = null;
        try {
            // Convert system. in to a character stream using a conversion stream
            InputStreamReader isr = new InputStreamReader(System.in);
            // Create an input character cache stream
            br = new BufferedReader(isr);

            while (true){
                System.out.println("Please enter:");
                String data = br.readLine();
                if (data.equalsIgnoreCase("e") | |"exit".equalsIgnoreCase(data)){
                    System.out.println("Program exit");
                    break; } System.out.println(data.toUpperCase()); }}catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(br ! =null)
                br.close();
            } catch(IOException e) { e.printStackTrace(); }}}}Copy the code

Running results:

9. Print stream

Print Flow Overview

Print flow is also a type of processing flow.

The implementation converts the data format of the basic data type to string output.

Print stream: PrintStreamFPrintWriter

  • Provides a series of overloaded print() and println() methods for output of a variety of data types

  • The output of PrintStream and PrintWriter does not throw IOException

  • PrintStream and PrintWriter have automatic flush

  • All characters printed by PrintStream are converted to bytes using the platform’s default character encoding. The PrintWriter class should be used in cases where characters are written instead of bytes.

  • System.out returns an instance of PrintStream

Print stream usage

Prints ASCL characters to the specified file

@Test
public void test1(a){
    PrintStream ps = null;
    try {
        File file = new File("D:\\io\\ascll.txt");
        FileOutputStream fos = new FileOutputStream(file);
        // Create a printout stream
        ps = new PrintStream(fos,true);// Automatic refresh mode (the output cache is flushed whenever newlines or bytes "\n" are written)
        if(ps ! =null) {// Change to output device, specify output to file, no longer output to console
            System.setOut(ps);
        }
        for (int i = 0; i < 255; i++) {// Outputs ASCLL characters
            System.out.print((char)i);
            if (i % 50= =0) {/ / 50 a newlineSystem.out.println(); }}}catch (FileNotFoundException e) {
        e.printStackTrace();
    } finally {
        try {
            if(ps ! =null)
            ps.close();
        } catch(Exception e) { e.printStackTrace(); }}}Copy the code

View the ascll.txt file:

10. Data flow

Overview of data flow

Data flow is also a type of processing flow.

To easily read or write out the Java language’s basic data types and String data, you can use data streams.

Data streams have two classes: DatalnputStream and DataOutputStream (for reading and writing data from the base data type, the String class). “Socket” streams on InputStream and OutputStream subclasses, respectively

Methods in DatalnputStream:

double readDouble()

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.

Use of data streams

Writes data in memory to a disk file

@Test
public void test2(a){
    DataOutputStream dos = null;
    try {
        // Create a node flow
        FileOutputStream fos = new FileOutputStream("data.txt");
        dos = new DataOutputStream(fos);

        // Write data to a file
        dos.writeUTF("A thousand miles to go.");
        dos.flush();
        dos.writeInt(18);
        dos.flush();
        dos.writeBoolean(true);
        dos.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if(dos ! =null)
            dos.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

To read data from a disk file and print it to the console:

@Test
public void test3(a){
    DataInputStream dis = null;
    try {
        FileInputStream fis = new FileInputStream("data.txt");
        dis = new DataInputStream(fis);

        // Data is read in the same order as data is written
        String name = dis.readUTF();
        int age = dis.readInt();
        boolean isMan = dis.readBoolean();
        System.out.println(name);
        System.out.println(age);
        System.out.println(isMan);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if(dis ! =null)
            dis.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

View console output:

Object flow

11.1 Overview of object flow

Object flow is one type of processing flow.

Object streams have two classes: ObjectInputStream and OjbectOutputSteam

A processing stream used to store and read data or objects of a primitive data type. Its power is that it can write objects from Java to and from the data source.

Serialization: Mechanism for holding primitive type data or objects with ObjectOutputStream

Deserialization: The mechanism by which data or objects of primitive types are read from ObjectInputStream

ObjectOutputStream and ObjectlnputStream cannot serialize static and LTRANSIENT (non-serializable) modified member variables

A serialization mechanism for objects

Object serialization mechanism allows the memory in the Java object into a platform independent binary stream, thereby allowing the binary stream lasting existence on disk, or this kind of binary stream transmission through the network to another network nodes (serialization), while other programs to obtain the binary stream, can be restored to the original Java objects (deserialization).

The benefit of serialization is that any object that implements the Serializable interface can be converted to byte data, which can be restored when saved and transferred.

Serialization is the mechanism by which both arguments and return values of the RMI (Remote Method invoke-remote Method call) procedure must be implemented, and RMI is the foundation of JavaEE. So serialization is the foundation of the JavaEE platform.

If you want an object to support serialization, you must make the class to which the object belongs and its properties serializable. In order for a class to be serializable, the class must implement one of the following two interfaces. Otherwise, NotSerializableException is thrown.

  • Serializable
  • Externalizable

Object stream serialization and deserialization of strings

Serialization:

@Test
public void test(a){

    ObjectOutputStream oos = null;
    try {
        // Create a stream of objects to serialize
        oos = new ObjectOutputStream(new FileOutputStream("object.data"));

        // Serialize the string object
        oos.writeObject(new String("A thousand miles to go."));
        oos.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if(oos ! =null)
            oos.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

Deserialization:

@Test
public void test1(a){
    ObjectInputStream ois = null;
    try {
        // Create a stream of objects to deserialize
        ois = new ObjectInputStream(new FileInputStream("object.data"));
        // Read the object data and print it
        Object str = ois.readObject();
        System.out.println((String) str);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        try {
            if(ois ! =null)
            ois.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

11.3. Custom classes implement serialization and deserialization

Custom classes:

package io;

import java.io.Serializable;
//1. Implement Serializable interface
public class Person implements Serializable {

    //2. Add the serialized version number
    private static final long serialVersionUID = 434543632352672L;

    //3. All attributes must also be serializable
    private int id;
    private String name;

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

    public int getId(a) {
        return id;
    }

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

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

Serialization version number:

Classes that implement the Serializable interface have a static constant representing the serialized version identifier: private Static Final Long serialVersionUID.

SerialVersionUID is used to indicate compatibility between different versions of a class. In short, the purpose is to versionize serialized objects and determine whether the versions are compatible when de-versioning.

If the class does not explicitly define this static constant, its value is automatically generated by the Java runtime environment based on 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.

Simply put, Java’s serialization mechanism verifies version consistency by determining the serialVersionUID of a 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, the serialVersionUID is considered the same and can be deserialized. Otherwise, an InvalidCastException occurs with an inconsistent serialization version.

Serialization:

@Test
public void test(a){

    ObjectOutputStream oos = null;
    try {
        // Create a stream of objects to serialize
        oos = new ObjectOutputStream(new FileOutputStream("object.data"));

        // serialize the word object
        oos.writeObject(new Person(1."A thousand miles to go."));
        oos.flush();
        oos.writeObject(new Person(2."Gods"));
        oos.flush();
        oos.writeObject(new Person(3."Taoxian"));
        oos.flush();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            if(oos ! =null)
            oos.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

Deserialization:

@Test
public void test1(a){
    ObjectInputStream ois = null;
    try {
        // Create a stream of objects to deserialize
        ois = new ObjectInputStream(new FileInputStream("object.data"));
        Object str = ois.readObject();
        Object str1 = ois.readObject();
        Object str2 = ois.readObject();

        System.out.println((Person) str);
        System.out.println((Person) str1);
        System.out.println((Person) str2);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {
        try {
            if(ois ! =null)
            ois.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

Random access file stream

12.1 overview of Random Access File flow

Random access file streams are also a type of processing stream.

The RandomAccessFile stream class is RandomAccessFile. RandomAccessFile can be used as either an input stream or an output stream.

RandomAccessFile is declared in the java.io package, but inherits directly from the java.lang.Object class. And it implements the Datalnput and DataOutput interfaces, which means that this class can read and write.

The RandomAccessFile class supports “random access”, which allows a program to read and write files by jumping directly to any part of the file:

  • Supports access to only part of a file
  • Appending to existing files is also supported

The RandomAccessFile object contains a record pointer that identifies the current read/write location.

The RandomAccessFile class object can freely move the record pointer:

  • Long getFilePointer() : Gets the current position of the file record pointer
  • Void seek(long pos) : Locate the file record pointer to the POS position

The constructor:

public RandomAccessFile(File file,String mode)

public RandomAccessFile(String name, String mode)

Creating an instance of the RandomAccessFile class requires specifying a mode parameter that specifies the access mode for RandomAccessFile:

  • R: Open it in read-only mode
  • 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 is read. An exception occurs if the read file does not exist.

If the mode is RW read/write, the file will be created if it does not exist, and will not be created if it exists.

12.2 RandomAccessFile implements read/write copy of non-text files

@Test
public void test3(a){
    RandomAccessFile raf = null;
    RandomAccessFile raf1 = null;

    try {
        // Create a RandomAccessFile object that opens the file in read-only mode
        raf = new RandomAccessFile("1.jpg"."r");
        // Create a RandomAccessFile object that opens the file in read and write mode
        raf1 = new RandomAccessFile("4.jpg"."rw");

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

12.3 RandomAccessFile implements data reading and writing

If RandomAccessFile is used as the output stream, the file will be created if it does not exist. If the written file already exists, the content of the original file is overwritten from the beginning.

@Test
public void test4(a){
    RandomAccessFile raf = null;
    try {
        // Create a RandomAccessFile object that opens the file in read and write mode
        raf = new RandomAccessFile("hello1.txt"."rw");

        raf.write("abcdefg".getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(raf ! =null) {try {
                raf.close();
            } catch(IOException e) { e.printStackTrace(); }}}}Copy the code

12.4 RandomAccessFile implements data insertion

@Test
public void test5(a){

    RandomAccessFile raf = null;
    try {
        raf = new RandomAccessFile("hello3.txt"."rw");

        // Position the file record pointer to the position marked 3 (starting from 0), which is the insertion position
        raf.seek(3);

        // Create StringBuilder to store the string after the insertion position
        StringBuilder sb = new StringBuilder((int) new File("hello1.txt").length());
        int len ;
        byte[] buffer = new byte[1024];
        while((len = raf.read(buffer)) ! = -1){
            sb.append(new String(buffer,0,len));
        }
        // Set the corner to 3
        raf.seek(3);
        raf.write("xxx".getBytes());

        // Write back the string in StringBuilder
        raf.write(sb.toString().getBytes());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if(raf ! =null) {try {
                raf.close();
            } catch(IOException e) { e.printStackTrace(); }}}}Copy the code

Insert before:

After the insert: