Java File and IO stream study notes

The data stored in the memory is temporary, but it will be lost when the power is cut off or the program terminates.

The hard disk can store data for a long time. Even if the power is cut off and the program is terminated, it will not be lost.

File

  • File is a class under the java.io. package, an object of the File class, used to represent files of the current operating system (can be a file or a folder)
  • Can obtain file information (size, file name, modification time)
  • Determine the file type
  • Create a file or folder
  • Delete files or folders…
  • But the File class can only operate on the file itself and cannot read or write the data stored in the file
Create File object
Constructor illustrate
public File(String pathname) Create file object based on file path
public File(String parent,String child) Create file objects based on parent path and child path names
public File(File parent,String child) Create a file object based on the file object corresponding to the parent path and the name of the subpath

Case

Main.java

import java.io.File;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        // 创建一个File对象,指代某个具体的文件
        File file = new File("C:\\Users\\huihui\\Desktop\\test.txt");
        System.out.println(file); // C:\Users\huihui\Desktop\test.txt
        System.out.println(file.length()); // 文件大小 0
        File file1 = new File("C:/Users/huihui/Desktop/test.txt");
        System.out.println(file1); // C:\Users\huihui\Desktop\test.txt
        File file2 = new File("C:" + File.separator +"Users"+ File.separator + "huihui"+ File.separator + "Desktop"+ File.separator + "test.txt");
        System.out.println(file2); // C:\Users\huihui\Desktop\test.txt
    }
}

Note: The File object can also refer to a non-existent file path

Main.java

import java.io.File;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File file = new File("aa/bb/cc");
        System.out.println(file.length()); // 0
        // 可以通过exists()方法判断文件是否存在
        System.out.println(file.exists()); // false
    }
}
path
  • Paths are divided into absolute paths (with drive letter) and relative paths (without drive letter)
import java.io.File;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        // 据对路径,带盘符(是种写死的路径)
        File file = new File("D:\\Idea\\Codeing\\Day01\\src\\Demo\\Student.java");
        System.out.println(file); // D:\Idea\Codeing\Day01\src\Demo\Student.java
        // 相对路径,不带盘符(是种灵活的路径),默认回去当前工程下寻找文件
        File file1 = new File("src\\Demo\\Student.java");
        System.out.println(file1); // src\Demo\Student.java
    }
}
method
Determine file type and obtain file information

Insert image description here

Case

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.logging.SimpleFormatter;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File file = new File("C:\\Users\\huihui\\Desktop\\test.txt");
        // 1. exists() 文件是否存在
        System.out.println(file.exists()); // true
        // 2. isFile() 判断是否是文件
        System.out.println(file.isFile()); // true
        // 3. isDirectory() 判断是否是文件夹
        System.out.println(file.isDirectory()); // false
        // 4. getName() 获取文件的名称包括后缀
        System.out.println(file.getName()); // test.txt
        // 5. length() 获取文件大小,返回字节个数
        System.out.println(file.length()); // 0
        // 6. laseModified() 获取文件的最后修改时间,默认返回的是时间戳
        // System.out.println(file.lastModified()); // 1696232257337
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println(sdf.format(file.lastModified())); // 2023-10-02 15:37:37
        // 7. getPath() 获取创建文件对象时,使用的路径(你写的是什么路径,它就会返回什么路径)
        System.out.println(file.getPath()); // C:\Users\huihui\Desktop\test.txt
        // 8. getAbsolutePath() 获取绝对路径
        System.out.println(file.getAbsolutePath()); // C:\Users\huihui\Desktop\test.txt
    }
}
Create or delete files

Insert image description here

Case

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

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 1. createNewFile() 创建一个新的文件,但是需要抛出异常。返回一个布尔值,如果存在,再创建就会返回false
        File file = new File("D:\\Idea\\Codeing\\Day01\\src\\Demo\\test.txt");
        System.out.println(file.createNewFile()); // true
        // 2. mkdir() 用于创建文件夹,但是只能创建一级文件夹。返回一个布尔值
        File f2 = new File("D:\\Idea\\Codeing\\Day01\\src\\Demo01");
        System.out.println(f2.mkdir()); // true
        // 3. mkdirs() 用于创建文件夹,可以创建多级文件夹
        File f3 = new File("D:/Idea/Codeing/Day01/src/Demo02/aa/bb");
        System.out.println(f3.mkdirs()); // true
        // 4. delete() 删除文件或者空文件,但是不能删除非空文件夹
    }
}
Traverse folders

FileClass providestraversal folder function

method illustrate
public String[] list() Get all "first-level file names" in the current directory and return a string array
public File[] listFiles() Get all "first-level file objects" in the current directory and return an array of file objects

UsagelistFilesNotes:

  • When the main call is a file or the path does not exist, returnnull
  • When the main call is an empty folder, return an array with a length of 0
  • When the main folder is a folder with content, put the paths of all first-level files and folders in theFilearray and return
  • When the main focus is a folder and there are hidden files in it, put the paths of all files and folders in it in the File array and return it, including hidden files
  • When the main call is a folder, but there is no permission to access the folder, returnnull
import java.io.File;
import java.util.Arrays;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File file = new File("D:\\Idea\\Codeing\\Day01\\src\\Demo");
        // 1. public String[] list(): 获取当前目录下所有的 "一级文件名称"
        String[] list = file.list();
        System.out.println(Arrays.toString(list)); // [Student.java, test.txt]
        // 2. public File[] listFiles(): 获取当前目录下所有的 "一级文件对象"
        File[] files = file.listFiles();
        for (File file1 : files) {
    
    
            System.out.println(file1.isFile()); // true true
            System.out.println(file1.getAbsolutePath()); // 
        }
    }
}
recursion

Case 1: Modify file serial number

import java.io.File;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        // 改变某个文件夹下的文件的序号,要求从19开始
        File f = new File("C:\\Users\\huihui\\Desktop\\test");
        // 1. 得到里面所有的文件对象
        File[] files = f.listFiles();
        for (File file : files) {
    
    
            String name = file.getName();
            String start = name.substring(0, name.indexOf("."));
            String end = name.substring(name.indexOf("."));
            String newName = (Integer.valueOf(start) + 18) + end;
            // 开始改名
            file.renameTo(new File(f, newName));
        }
    }
}

Recursion is when the method calls itself. Recursion must have an end condition, otherwise it will recur infinitely, causing stack memory to overflow (because the method will enter the stack, and it will be pushed into the stack every time it is called, but if it never comes out, the method in the stack memory will be There will be more and more, and it will overflow)

Recursive form:

  1. Direct recursion: the method calls itself
  2. Indirect recursion: A method calls other methods, and other methods call back the method itself.

Direct recursion:

public class Main {
    
    
    public static void main(String[] args) {
    
    
        print(0);
    }

    // 直接递归:方法内部直接调用自己
    public static void print(int num) {
    
    
        if(num < 10) {
    
    
            System.out.println("打印输出");
            print(++num);
        }
    }
}

Indirect recursion:

public class Main {
    
    
    public static void main(String[] args) {
    
    
        print(0);
    }

    public static void print(int num) {
    
    
        temp(num);
    }
    // 间接递归:别的方法调用自己
    public static void temp(int num) {
    
    
        if(num < 10) {
    
    
            System.out.println("打印输出");
            print(++num);
        }
    }
}
Find factorial
public class Main {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(print(5)); // 120
    }

    // 计算结阶乘
    public static int print(int num) {
    
    
        if(num == 1) return 1;
        return print((num - 1)) * num;
    }
}

Insert image description here

Find the sum of 1-n
public class Main {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(sum(5)); // 15
    }

    // 计算1-n的和
    public static int sum(int num) {
    
    
        if(num == 1) return 1;
        return sum(num - 1) + num;
    }
}
Monkey eats peach

The monkey picked some peaches on the first day and ate them immediately. He felt they were not enough, so he ate one more. The next day I ate the same amount of peaches left over from the day before. I felt they were not enough, so I ate one more. From now on, I will eat half of the remaining peaches from yesterday plus one. By the tenth day there was only one peach left. Ask the monkey how many peaches he picked?

f(x) - f(x)/2 - 1 = f(x + 1) // Subtract half of what you ate the day before yesterday and then subtract 1 from what you ate yesterday, which is today’s

public class Main {
    
    
    public static void main(String[] args) {
    
    
        System.out.println(sum(1)); // 1534
    }

    // 计算1-n的和
    public static int sum(int num) {
    
    
        if(num == 10) return 1;
        return 2 * sum(num + 1) + 2;
    }
}
Search files

Search from the diskD: for the file, find it and directly output the location and open itQQScLauncher.exe

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

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        String path = getPath(new File("D:\\QQ\\Bin"), "QQScLauncher.exe");
        System.out.println(path); // C:\Users\huihui\Desktop\Test\test.txt
    }

    // 在c盘中找到 test.txt 文件,并输出位置
    public static String getPath(File dir, String fileName) throws IOException {
    
    
        if(dir == null || !dir.exists() || dir.isFile()) return "您输入的路径有误";
        // 首先遍历一级文件
        File[] files = dir.listFiles();
        // 判断当前目录下是否存在一级文件对象,一级是否可以拿到一级文件对象
        if(files != null && files.length > 0) {
    
    
            // 找到里面的文件并对比
            for (File file : files) {
    
    
                if(file.isFile() && file.getName().contains(fileName)) {
    
    
                    // 打开文件 运行时对象
                    Runtime runtime = Runtime.getRuntime();
                    runtime.exec(file.getAbsolutePath());
                    return file.getAbsolutePath();
                } else {
    
    
                    getPath(file, fileName);
                }
            }
        }
        return "没有搜索到";
    }
}
Delete non-empty folders
import java.io.File;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        delFile(new File("C:/Users/huihui/Desktop/kong"));
    }

    // 删除非空文件夹
    public static void delFile(File file) {
    
    
        // 判空,不存在或者传的为空则不处理
        if(!file.exists() || file == null) return;
        // 如果是文件,则直接删除
        if(file.isFile()) {
    
    
            file.delete();
            return;
        }
        // 存在且是文件夹
        File[] files = file.listFiles(); // 拿到下面的一级文件对象
        if(files == null) return; // 如果文件夹为空(没有权限),则不处理
        // 有权限,不为空的文件夹,遍历进行删除里面的内容,并且最后要把自己空的文件夹删除
        for (File f : files) {
    
    
            if(f.isFile()) {
    
     // 是文件,直接删除
                f.delete();
            } else {
    
     // 文件夹,接着递归
                delFile(f);
            }
        }
        file.delete(); // 最后别忘了把自己空的文件夹删除
    }
}

character set

Insert image description here

UTF-8

Key points:

  • ASCIICharacter set: only English, numbers, symbols, etc. Occupies 1 byte
  • GBKCharacter set: Chinese characters occupy 2 bytes, English and numbers occupy 1 byte
  • UTF-8Character set: Chinese characters occupy 3 bytes, English and numbers occupy 1 byte

The character set used for character encoding and the character set used for decoding must be consistent, otherwise garbled characters will appear.

However, numbers and English generally do not appear garbled, because most character sets must be compatible.ASCII

Encoding and decoding

Encoding: Encode characters into bytes according to the specified character set

Decoding: Decode bytes into characters according to the specified character set

coding
method name illustrate
byte[] getBayes() Encode the String into a series of bytes using the platform's default character set and store the result in a new byte array
byte[] getBytes(String charsetName) Encode the String into a series of bytes using the specified character set and store the result in a new byte array
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class Main {
    
    
    public static void main(String[] args) throws UnsupportedEncodingException {
    
    
        String str = "a的1";
        // 编码
        byte[] b1 = str.getBytes(); // 按照平台默认的字符编码规则编码
        System.out.println(Arrays.toString(b1)); // [97, -25, -102, -124, 49] 97:a 49:1 中间3个表示中文
        byte[] gbks = str.getBytes("GBK");
        System.out.println(Arrays.toString(gbks)); // [97, -75, -60, 49] gbk编码规则中中文是2个字节
    }
}
decoding
method name illustrate
String(byte[] bytes) Constructs a new String by decoding the specified byte array using the platform's default character set
String(byte[] bytes, String charsetName) Construct a new String by decoding the specified character set and specifying the concession array.
import java.io.UnsupportedEncodingException;
import java.util.Arrays;

public class Main {
    
    
    public static void main(String[] args) throws UnsupportedEncodingException {
    
    
        String str = "a的1";
        // 编码
        byte[] b1 = str.getBytes(); // 按照平台默认的字符编码规则编码
        System.out.println(Arrays.toString(b1)); // [97, -25, -102, -124, 49] 97:a 49:1 中间3个表示中文
        byte[] gbks = str.getBytes("GBK");
        System.out.println(Arrays.toString(gbks)); // [97, -75, -60, 49] gbk编码规则中中文是2个字节
        // 解码
        String s = new String(b1);
        System.out.println(s); // a的1
        String gbk = new String(gbks, "GBK");
        System.out.println(gbk); // a的1
    }
}

I流

Insert image description here

  • File represents a file. AndIOstream can read and write data

Insert image description here

application:

Insert image description here

Classification:
Insert image description here

specific system

Insert image description here

Input and output are based on memory. The program runs in the memory, and the reading and writing speed is fast, but if the power is turned off or shut down, the data will be cleared. The hard disk (also called a disk) can store data permanently, but its read and write speeds are relatively slow.

Input: The disk inputs into the memory. It can also be said that the memory reads data from the disk.

Output: The memory outputs to the disk. It can also be said that the memory writes data to the disk.

If you want to read and write data from memory and disk, you must establish a connection, and this connection is a stream. Similar to a pipe, except that data flows in the pipe

Data is divided into bytes and characters. Bytes can operate on any file, while characters focus on operating various text files (such astxtfiles.javaFile...)

input stream
  • Then according to the smallest unit of the file, it can be divided into byte input stream and character input flow
Byte input stream
  • is represented byInputStream abstract class. The more commonly used implementation class isFileInputStream

effect:

  • Based on the memory, the data in the disk file can be read into the memory in bytes (that is, read into the program, because the program is run in the memory)

First, create a pipeline to connect disk and memory

Constructor illustrate
public FileInputStream(File file) Create a byte input stream pipe to connect to the source file
public FileInputStream(String pathName) Create a byte input stream pipe to connect to the source file

Then you can read and write using the method provided by Java

method name illustrate
public int read() Returns one byte each time it is read. If no data is found to be read, -1 will be returned.
public int read(byte[] buffer) Each time a byte array is used to read data, the number of bytes read in the byte array is returned. If there is no data to read, -1 will be returned.

test file

a测试文件
Read a byte
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建管道链接
        InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 读数据,一次只读一个字节
        int read = fis.read();
        System.out.println((char) read); // a
        // 最后别忘关闭通道(关闭流)
        fis.close();
    }
}

Optimize the above transformation

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建管道链接
        InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 读数据,一次只读一个字节
        int num; // 记录读取的字符
        while ((num = fis.read()) != -1) {
    
     // 不等于-1说明还有字节
            System.out.print((char) num); // a测试文件
        }
        // 最后别忘关闭通道(关闭流)
        fis.close();
    }
}

But there is a problem with this: when reading Chinese characters, the characters will be garbled (because in UTF8, Chinese characters are 3 bytes, and you can only read one at a time, which will definitely cause garbled characters), and the reading performance is not high.

Read multiple bytes
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建管道链接
        InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 读数据,可以自己设定一次读多少个字节
        byte[] bytes = new byte[3];

        // 第一次读取
        // read(byte[] buffer) 返回的是一次读取了多少个字节个数。如果最后一次读取,不到3个字节,那有几个字节,它就是几
        int len = fis.read(bytes);
        System.out.println(len); // 3
        // bytes 中存放的就是读取的3个字节 ['a','1','2']
        System.out.println(new String(bytes)); // a12

        // 第二次读取
        int len2 = fis.read(bytes);
        System.out.println(len2); // 2 因为最后的字节只有2个,不到3个,所以为2
        // bytes 中存放的就是读取的最新的3个字节 ['3','4','2'] 最后一个因为没有,所以还是用的原先的
        System.out.println(new String(bytes)); // 342
        // 但是显然上面的是不对的,正确的应该是 34 不应该有2
        System.out.println(new String(bytes, 0, len2)); // 34 第2个参数是开始位置,第3个参数是结束位置
    }
}

Perform loop optimization

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建管道链接
        InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 读数据,可以自己设定一次读多少个字节
        byte[] bytes = new byte[3];

        // 当读取的长度不为我们设定的3时,就说明读取到到最后一个了
        int len; // 每次读取的字节长度
        while (((len = fis.read(bytes)) != -1)) {
    
    
            String s = new String(bytes, 0, len);
            System.out.println(s); // a12 34
        }
        // 关闭管道
        fis.close();
    }
}

But by reading multiple bytes at once, Chinese characters are still unreadable. But the file must be read in Chinese, so how do we solve the problem of Chinese garbled characters?

In fact, there is a way to define a byte array as large as the file and read all the bytes of the file at once, so that Chinese garbled characters will not appear.

Method 1 to solve Chinese garbled characters

File read:

a中文
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建管道链接
        InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 获取文件大小
        File file = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        long length = file.length(); // 硬盘中的存储空间比较大,所以用的long类型
        // 读数据,可以自己设定一次读多少个字节
        byte[] bytes = new byte[(int)length]; // 内存里的存储空间比较小,所以用的int类型

        fis.read(bytes);
        System.out.println(new String(bytes)); // a中文
        fis.close();
    }
}

But the above method can actually only read small files. Files exceeding the int range cannot be read at once

Method 2 to solve Chinese garbled characters

JavaOfficially provides a method forInputStrem to directly read all the bytes of the file into a byte array and return it

public byte[] readAllbytes() throw IOException // Directly bump the byte data of the file object corresponding to the current byte input stream into a byte array and return it

Then method 1 above can be simplified as follows

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建管道链接
        InputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 获取全部字节文件,并返回到一个新的字节数组
        byte[] bytes = fis.readAllBytes();

        String s = new String(bytes);
        System.out.println(s); // a中文
        fis.close();
    }
}
character input stream
  • is represented byReader abstract class. The more commonly used implementation class isFileReader

effect:

  • Based on the memory, the data in the file can be read into the memory in the form of characters.

First, create a pipeline to connect disk and memory

Constructor illustrate
public FileReader(File file) Create a character input stream pipeline and connect it to the file
public FileReader(String pathName) Create a character input stream pipeline and connect it to the source file

Then there is the method to write

method name illustrate
public int read() Returns one character each time it is read. If no data is found to be read, -1 will be returned.
public int read(char[] buffer) Each time a character array is used to read data, the number of characters read in the character array is returned. If no data is found to be read, -1 will be returned.
read a character
import java.io.FileReader;
import java.io.IOException;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建一个字符链接管道
        FileReader fr = new FileReader("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 然后开始读,一次读取一个字符
        int read = fr.read();
        System.out.println((char) fr.read());
        fr.close();
    }
}

The above can be optimized

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

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建一个字符链接管道
        FileReader fr = new FileReader("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 然后开始读,一次读取一个字符
        int num;
        while ((num = fr.read()) != -1) {
    
    
            System.out.println((char) num);
        }
        fr.close();
    }
}
Read multiple characters
import java.io.FileReader;
import java.io.IOException;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建一个字符链接管道
        FileReader fr = new FileReader("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        char[] chars = new char[3];
        // 读取多个字符
        int len; // 记住每次读取了多少个字符
        while ((len = fr.read(chars)) != -1) {
    
    
            System.out.print(new String(chars,0,len)); // 被复制的内容
        }
        fr.close();
    }
}
output stream
  • Then according to the smallest unit of the file, it can be divided into byte output stream and character output flow
Byte output stream
  • is represented byOutputStream abstract class. The more commonly used implementation class isFileOutputStream

effect:

  • Based on the memory, write the data in the memory to the file in the form of bytes

First, create a pipeline to connect disk and memory

Constructor illustrate
public FileOutputStream(File file) Create a byte output stream pipe connected to the source file
public FileOutputStream(String filePath) Create a byte output stream pipe connected to the source file
public FileOutputStream(File file,boolean append) Create a byte output stream pipeline connected to the source file object, and data can be appended
public FileOutputStream(String filePath,boolean append) Create a byte output stream pipeline connected to the source file object, and data can be appended

Then you can read and write using the method provided by Java

method name illustrate
public void write(int a) Write a byte out
public void write(byte[] buffer) Write a byte array into it
public void write(byte[] buffer, int pos, int len) Write part of a byte array into it
public void close() throw IOException close stream

Test file (empty file)

Write one byte to disk
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建一个内存到硬盘的管道
        OutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 往磁盘中写入一个字节
        fos.write(97); // 97 ASCII 表示a
        fos.write('b'); // ''  单引号包裹的本来就是一个字节 byte类型
        fos.close();
    }
}

cannot be written directly into Chinese, because in utf-8 encoding, one Chinese character occupies 3 bytes, but only one byte is written here. Therefore, writing Chinese characters will be garbled, but we can add Chinese characters by writing a byte array, and the corresponding characters can be obtained by calling the method of String section arraygetBytes()

Add Chinese
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建一个内存到硬盘的管道
        OutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 往磁盘中写入一个字节
        fos.write(97); // 97 ASCII 表示a
        fos.write('b'); // ''  单引号包裹的本来就是一个字节 byte类型
        // 添加中文 通过 String 的 getBytes() 方法可以直接得到一个字节数组
        byte[] bytes = "中文".getBytes();
        fos.write(bytes);
        fos.close();
    }
}
Specify the added part
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建一个内存到硬盘的管道
        OutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 往磁盘中写入一个字节
        fos.write(97); // 97 ASCII 表示a
        fos.write('b'); // ''  单引号包裹的本来就是一个字节 byte类型
        // 添加中文 通过 String 的 getBytes() 方法可以直接得到一个字节数组
        byte[] bytes = "中文".getBytes();
        fos.write(bytes);
        // 当然,也可以指定添加的部分
        byte[] bytes2 = "添加前两个字".getBytes();
        fos.write(bytes2,0,6); // 一个中文是3个字节,所以添加前两个字,只需要添加6个字节
        fos.close();
    }
}

But the above additions will directly replace everything in the original file. Sometimes, we actually don’t want the added content to replace the original content, so we need to specify the added content when creating the pipeline (the second parameter of the constructor is true)

Append content later

test file

文件原本的内容
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 首先创建一个内存到硬盘的管道,如果是追加内容,则需要把第二个参数设为true
        OutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt",true);
        // 往磁盘中写入一个字节
        fos.write(97); // 97 ASCII 表示a
        fos.write('b'); // ''  单引号包裹的本来就是一个字节 byte类型
        // 添加中文 通过 String 的 getBytes() 方法可以直接得到一个字节数组
        byte[] bytes = "中文".getBytes();
        fos.write(bytes);
        // 当然,也可以指定添加的部分
        byte[] bytes2 = "添加前两个字".getBytes();
        fos.write(bytes2,0,6); // 一个中文是3个字节,所以添加前两个字,只需要添加6个字节
        // 添加换行
        fos.write("\r\n".getBytes());
        fos.close();
    }
}

Last file displayed

文件原本的内容
ab中文添加
File copy
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 1. 首先创建一个输入流,把需要复制的内容用一个字节数组存储起来
        FileInputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 1.1 创建一个存储字节的数组
        byte[] bytes = fis.readAllBytes();
        
        // 2. 把存起来的字符数组输出到指定的文件里去
        FileOutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\get.txt", true);
        fos.write(bytes);

        fis.close();
        fos.close();
        System.out.println("复制完成");
    }
}

But if the file above is particularly large, errors may occur. Here's a more general approach

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {
    
    
    public static void main(String[] args) throws IOException {
    
    
        // 1. 首先创建一个输入流,把需要复制的内容用一个字节数组存储起来
        FileInputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        // 2. 把存起来的字符数组输出到指定的文件里去  这里后面不加true也是追加,因为同一个流不会覆盖
        FileOutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\get.txt", true);

        // 3. 创建一个字节数组,负责转移字节数据
        byte[] bytes = new byte[1024]; // 先给个1kb
        // 4. 然后开始循环写入
        int len; // 记录每次读取了多少个字节
        while ((len = fis.read(bytes)) != -1) {
    
    
            fos.write(bytes,0,len);
        }

        fis.close();
        fos.close();
        System.out.println("复制完成");
    }
}
character output stream
  • is represented byWriter abstract class. The more commonly used implementation class isFileWriter
  • After the character output stream outputs characters, the stream must be output or the stream must be closed before the written data can take effect.

effect:

  • Based on the memory, the data in the memory can be output to the disk in the form of characters.

First, create a pipeline to connect disk and memory

Constructor illustrate
public FileWriter(File file) Create a character output stream pipeline and connect it to the source file object
public FileWriter(String pathName) Create a character output stream pipeline and connect it to the source file path
public FileWriter(File file,Boolean append) Create a byte output stream pipeline connected to the source file object, and data can be appended
public FileWriter(String fillpath,boolean append) Create a byte output stream pipeline and connect it to the source file path to append data.

Then there is the method for output

method name illustrate
void write(int c) Write one character at a time. If no data is found to be written, -1 will be returned.
void write(String str) write a string
void write(String str, int off, int len) Write part of a string
void write(char[] cbuf) Write a character array
void write(char[] cbuf, int off, int len) Write part of a character array
Write one character to disk
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                // 创建链接管道
                Writer fw = new FileWriter(f);
                ) {
    
    
            // 一次写入磁盘一个字符
            fw.write(97);
            fw.write('b');
            fw.write('中');
            // 或者写一个字符串
            fw.write("国");
            // 或者写入字符串的一部分
            fw.write("人123",0,1);
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}
Write multiple characters
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                // 创建链接管道
                Writer fw = new FileWriter(f);
                ) {
    
    
            // 写入一个字符数组
            char[] chars = "1a中".toCharArray();
            fw.write(chars);
            // 直接写入一个字符串
            fw.write("几点开始");
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}
close stream
  • Call the stream'sclose method to close the channel of the stream. But sometimes, there may be some problems in the code, making it impossible to reach the close method normally, so error trapping is needed
tryCatch

try { // Code that may cause errors } catch (exception class name variable name) { // Error handling } finally { // It will be executed regardless of success or failure }

  • UnlessJVM terminates (System.exit()), the code in finally will definitely be executed
  • Function: GenerallyUsed to release resources after the program execution is completed
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Objects;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        // 快捷键:选中代码 ctrl + alt + t
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
    
    
            // 1. 首先创建一个输入流,把需要复制的内容用一个字节数组存储起来
            fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
            // 2. 把存起来的字符数组输出到指定的文件里去  这里后面不加true也是追加,因为同一个流不会覆盖
            fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\get.txt", true);

            // 3. 创建一个字节数组,负责转移字节数据
            byte[] bytes = new byte[1024]; // 先给个1kb
            // 4. 然后开始循环写入
            int len; // 记录每次读取了多少个字节
            while ((len = fis.read(bytes)) != -1) {
    
    
                fos.write(bytes,0,len);
            }

            System.out.println("复制完成");
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        } finally {
    
    
            try {
    
    
                if(Objects.isNull(fis)) fis.close();
                if(Objects.isNull(fos)) fos.close();
            } catch (IOException e) {
    
    
                throw new RuntimeException(e);
            }
        }
    }
}
tryWithResource
  • ratiotryCatchmore details
  • Only resource objects, such as stream objects, can be placed inside the brackets, and the stream will be automatically closed.
  • The resources will implement an AutoCloseableinterface, and the resources will have a close method, and will automatically call < /span>

try(define resource 1; define resource 2; ...) { // Code where exception may occur; } cache(exception class name variable name) { // Exception handling code; }

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        try(
                // 1. 首先创建一个输入流,把需要复制的内容用一个字节数组存储起来
                FileInputStream fis = new FileInputStream("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
                // 2. 把存起来的字符数组输出到指定的文件里去  这里后面不加true也是追加,因为同一个流不会覆盖
                FileOutputStream fos = new FileOutputStream("D:\\Idea\\Codeing\\Day01\\src\\get.txt", true);
                ) {
    
    
            // 3. 创建一个字节数组,负责转移字节数据
            byte[] bytes = new byte[1024]; // 先给个1kb
            // 4. 然后开始循环写入
            int len; // 记录每次读取了多少个字节
            while ((len = fis.read(bytes)) != -1) {
    
    
                fos.write(bytes,0,len);
            }

            System.out.println("复制完成");
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}

buffered stream

  • Wrap the original stream to improve the performance of reading and writing data from the original stream
Byte buffered input stream

Test Data

abcd

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\IDEA\\code\\hello\\src\\test.txt");
        try(
                FileInputStream fis = new FileInputStream(f);
                InputStream bis = new BufferedInputStream(fis);
                ) {
    
    
            byte[] bytes = new byte[3];

            int len;
            while ((len = bis.read(bytes)) != -1) {
    
     // 不为-1说明就有值
                System.out.print(new String(bytes, 0, len)); // abcd
            }
        } catch (Exception e){
    
    
            e.printStackTrace(); //打印错误信息
        }
    }
}
Byte buffered output stream
import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\IDEA\\code\\hello\\src\\test.txt");
        try(
                // 建立管道链接
                OutputStream os = new FileOutputStream(f,true);
                OutputStream bos = new BufferedOutputStream(os);
                ) {
    
    
            // 一次写入磁盘一个字节
            bos.write(97); // 97 ASCII中是a
            bos.write('b');
            // os.write('中'); // 添加中文是不行的,因为在utf8编码中,中文是3个字节,这里只添加一个,肯定不行
            // 一次写入磁盘多个字节
            byte[] bytes = "中国".getBytes();
            bos.write(bytes);
            // 一次写入指定个数的
            byte[] bytes1 = "abc".getBytes();
            bos.write(bytes1, 0, 2);
        } catch (Exception e){
    
    
            e.printStackTrace(); //打印错误信息
        }
    }
}
Character buffered input stream
import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\IDEA\\code\\hello\\src\\test.txt");
        try(
                // 建立管道链接
                Reader fr = new FileReader(f);
                Reader br =  new BufferedReader(fr);
                ) {
    
    
            // 1. 一次读取一个字符
            int r1 = br.read();
            System.out.println(r1); // 99 ASCII中表示c
            System.out.println((char) r1); // c
            // 2. 一次读取指定次数的字符
            char[] chars = new char[4];
            int len;
            while ((len = br.read(chars)) != -1) {
    
     // 只要不为-1,就说明还有值
                String s = new String(chars, 0, len);
                System.out.print(s); // eshishuju
            }
            // 3. 一次读取多个字符,并且指定位置和个数
            int r2 = br.read(chars, 0, 3);
            System.out.println(r2); // -1 因为上面读完了
        } catch (Exception e){
    
    
            e.printStackTrace(); // 打印错误信息
        }
    }
}
Character buffered output stream
import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\IDEA\\code\\hello\\src\\test.txt");
        try(
                // 建立管道链接
                Writer fw = new FileWriter(f);
                Writer bw =  new BufferedWriter(fw);
                ) {
    
    
            // 1. 一次写入磁盘一个字符
            bw.write(97);
            bw.write('b');
            bw.write('中');
            // 2. 一次写入一个字符数组
            char[] charArray = "你好呀".toCharArray();
            bw.write(charArray);
            // 3. 还可以直接写入字符串,这个就很方便呀
            bw.write("Java");
            // 4. 还可以指定起始位置和个数
            bw.write("Web",0,3);
        } catch (Exception e){
    
    
            e.printStackTrace(); // 打印错误信息
        }
    }
}

Conversion flow

character input conversion stream
InputStreamReader
  • Solve the problem of garbled text content when characters are read in different encodings
  • Solution: First obtain the original byte stream of the file, and then convert it into a character input stream according to its real character set encoding, so that the characters in the character input stream will not be garbled.
Constructor illustrate
public inputStreamReader(InputStream is) Convert the original byte input stream into a character input stream according to the default encoding of the code (the same effect as using FileReader directly)
public InputStreamReader(InputStream is,String charset) Convert the original byte input stream into a character input stream according to the specified character set encoding

File A GBK encoding format

中几点开始
import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                Reader br = new BufferedReader(new FileReader(f));
                ) {
    
    
            // � 因为编译器默认编码是utf8,但是文件里面的编码是gbk 所以乱码了
            System.out.println((char) br.read());
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}

The solution is character input conversion stream

import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                InputStream is = new FileInputStream(f);
                // 转成对应编码的字节输入流
                Reader isr = new InputStreamReader(is, "GBK");
                // 这样再操作就不会有乱码问题了
                Reader br = new BufferedReader(isr);
                ) {
    
    
            int c;
            while ((c = br.read()) != -1) {
    
    
                System.out.print((char) c);
            }
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}
character output conversion stream
OutputStreamWrite
  • You can control what character set encoding is used for written characters
  • Solution: Get the byte output stream, and then convert it into a character output stream according to the specified character set encoding. The characters written out in the future will be encoded in this character set.
Constructor illustrate
public OutputStreamWriter(OutStream os) The original byte output stream can be converted into a character output stream according to the default encoding of the code.
public OutputStreamWriter(OutputStream os,String charset) The original byte output stream can be converted into a character output stream according to the specified character set encoding.

File A GBK encoding format

import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                Writer bw = new BufferedWriter(new FileWriter(f));
                ) {
    
    
            bw.write("你好呀"); // 啊浣犲ソ鍛�     乱码了,因为写入的是utf8编码的字符
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}

The solution is character output conversion stream

import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                OutputStream fos = new FileOutputStream(f, true);
                // 把原始的字节输入流转成固定格式的输出流
                Writer psw = new OutputStreamWriter(fos, "GBK");
                Writer bw = new BufferedWriter(psw);
                ) {
    
    
            bw.write("你好呀"); // 啊你好呀
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}
Controls the character set used for written characters

There are two ways to achieve this:

  1. Call themethod provided by StringgetBytes

String d = "Hello"; byte[] bytes = d.getBytes("GBK");

  1. Implemented using character output conversion stream

print stream

  • Printing stream can make printing data more convenient and efficient, and you can print whatever you want.
printStream
  • Belongs to the byte output stream
Constructor illustrate
public PrintStream(OutputStream/File/String) The print stream goes directly to byte output stream/file/filepath
public PrintStream(String fileName,Charset charset) 可以指定写出去的字符编码
public PrintStream(OutputStream out, boolean autoFlush) 可以指定实现自动刷新
public PrintStream(OutputStream out, bollean autoFlush, String encoding) 可以指定实现自动刷新,并可指定字符的编码

写数据的方法

方法名 说明
public void println(Xxx xx) 打印任意类型的数据出去,自带换行
public void write(int/byte[]/byte[]的一部分) 可以支持写字节数据进去

基本使用

import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                PrintStream ps = new PrintStream(f);
                ) {
    
    
            ps.println(97);
            ps.println('b');
            ps.println("你好呀"); // 97 \n b \n 你好呀
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}

指定字符集

import java.io.*;
import java.nio.charset.Charset;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                // 指定写入的编码格式
                PrintStream ps = new PrintStream(f, Charset.forName("GBK"));
                ) {
    
    
            ps.println(97);
            ps.println('b');
            ps.println("你好呀"); // 97 \n b \n 你好呀
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}
PrintWriter
  • 属于字符输出流
构造器 说明
public PrintWriter(OutputStream/Writer/File/String) 打印流直接通向字节输出流/字符输出流/文件/文件路径
public PrintWriter(String fileName,Charset charset) 可以指定写出去的字符编码
public PrintWriter(OutputStream out/Writer, boolean autoFlush) 可以指定实现自动刷新
public PrintWriter(OutputStream out, bollean autoFlush, String encoding) 可以指定实现自动刷新,并可指定字符的编码

写数据的方法

方法名 说明
public void println(Xxx xx) 打印任意类型的数据出去,自带换行
public void write(int/String/char[]) 可以支持写字符数据出去

基本使用

import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                PrintWriter pw = new PrintWriter(f);
        ) {
    
    
            pw.println(97);
            pw.println('a');
            pw.println("你好呀"); // 97 \n b \n 你好呀
        } catch (IOException e) {
    
    
            throw new RuntimeException(e); 
        }
    }
}

指定字符集

import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                PrintWriter pw = new PrintWriter(f,"GBK");
        ) {
    
    
            pw.println(97);
            pw.println('a');
            pw.println("你好呀");
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}
追加数据
  • 因为PrintStreamPrintWriter是高级流,所以不能直接追加数据,但是我们在调用构造器的时候,可以传入一个低级输出流,在低级输出流中可以指定追加
import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                PrintWriter pw = new PrintWriter(new FileOutputStream(f, true));
        ) {
    
    
            pw.println(97);
            pw.println('a');
            pw.println("你好呀");
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}
区别
  • 打印数据的功能上一摸一样:都是使用方便,性能高效
  • PrintStream继承字节输出流OutputStream,因此支持字节数据的方法
  • PrintWriter继承字符输出流Writer,因此支持字符数据的方法
应用

输出语句的重定向,可以把输出语句的打印位置改到某个文件中去

import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        System.out.println("会打印文件外");
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                // PrintWriter pw = new PrintWriter(new FileOutputStream(f));
                PrintStream ps = new PrintStream(f);
        ) {
    
    
            // 把系统默认的打印流对象改成自己设置的打印流
            System.setOut(ps);

            System.out.println("会打印在文件里");
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}

数据流

  • 操作的都是字节的
DataOutputStream
  • 属于字节输出流,允许把数据和其类型一并写出去
构造器 说明
public DataOutputStream(OutputStream out) 创建新数据输出流包装基本的字节输出流

方法

方法 说明
public final void writeByte(int v) throws IOException 将byte类型的数据写入基本的字节输出流
public final void writeInt(int v) throws IOException 将Int类型的数据写入基本的字节输出流
public final void writeDouble(Double v) throws IOException 将Double类型的数据写入基本的字节输出流
public final void writeUtf(String str) throws IOException 将字符串数据以UTF-8编码字节写入基本的字节输出流
public void write(int/byte[]/byte[]的一部分) 支持写字节数据出去

案例

import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                OutputStream fps = new FileOutputStream(f);
                // 写入数据和其类型,就需要用到数据流
                DataOutputStream dos = new DataOutputStream(fps);
        ) {
    
    
            // 写入一个字节
            dos.writeByte(97); // a
            // 写入一个数字
            dos.writeInt(97); // 97
            // 写入一个布尔
            dos.writeBoolean(true);
            // 写入一个小数
            dos.writeDouble(99.99);
            // 写入一个字符串
            dos.writeUTF("你好呀"); // a   a@X�\(� 	你好呀    这不是乱码,是有类型就这样
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}
DataInputStream
  • 属于字节输入流,用于读取数据输出流写出去的数据
构造器 说明
public DataInputStream(InputStream is) 创建新数据输入流包装基本的字节输出流

方法

方法 说明
public final void readByte() throws IOException 读取字节数据返回
public final int readInt() throws IOException 读取int类型的数据返回
public final double readDouble() throws IOException 读取double类型的数据返回
public final String readUtf() throws IOException 读取字符串数据返回(UTF-8)
public int readInt() / public int read(byte[]) 支持读字节数据进来

案例:读的顺序要跟写的顺序一样

import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
             InputStream fis = new FileInputStream(f);
             // 我们需要读取带有值和类型的,所以就需要用到数据输入流
             DataInputStream dis = new DataInputStream(fis);
        ) {
    
    
            // System.out.println(dis.read()); // 97
            System.out.println(dis.readByte()); // 97
            System.out.println(dis.readInt()); // 97
            System.out.println(dis.readBoolean()); // true
            System.out.println(dis.readDouble()); // 99.99
            System.out.println(dis.readUTF()); // 你好呀
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}

序列化流

  • 我们想把Java对象存进文件去,就需要用到对象序列化流
  • 则反序列化就是把存进去的对象序列化读取出来
  • 属于字节流
ObjectOutputStream
  • 可以把Java对象进行序列化:把Java对象存入到文件中去
  • transient修饰的成员可以不参与对象序列化
构造器 说明
public ObjectOutputStream(OutputStream out) 创建对象字节输出流,包装基础的字节输出流

方法

方法名 说明
public final void writeObject(Object o) throws IOException 把对象写出去

案例

Student.java

package Demo;
import java.io.Serializable;

// 注意:对象如果需要序列化,必须实现序列化接口
public class Student implements Serializable {
    
    
    private String name;
    private int age;
    // private double score;
    // transient 修饰,则这个成员变量将不参与序列化(因为有的时候,其实不想要某个属性展示的,例如密码)
    private transient double score;

    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 double getScore() {
    
    
        return score;
    }

    public void setScore(double score) {
    
    
        this.score = score;
    }

    public Student() {
    
    
    }

    public Student(String name, int age, double score) {
    
    
        this.name = name;
        this.age = age;
        this.score = score;
    }

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

Main.java

import Demo.Student;
import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Student zs = new Student("张三", 25, 100.00);

        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
             OutputStream fos = new FileOutputStream(f);
             // 我们要写入对象,就需要用到对象序列化流
             ObjectOutputStream ois = new ObjectOutputStream(fos);
        ) {
    
    
            ois.writeObject(zs);
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}
ObjectInputStream
  • 可以把Java对象进行反序列化:把存储在文件中的Java对象读入到内存中来
构造器 说明
public ObjectInputStream(InputStream is) 创建对象字节输入流,包装基础的字节输入流

方法

方法名 说明
public final Object readObject() 把存储在文件中的Java对象读出来

案例

import Demo.Student;
import java.io.*;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                InputStream fis = new FileInputStream(f);
                // 我们想要读取存储在文件中的对象,就需要对象反序列化
                ObjectInputStream ois = new ObjectInputStream(fis);
        ) {
    
    
            Student s1 = (Student) ois.readObject();
            System.out.println(s1);//Student{name='张三', age=25, score=0.0} 这里score并不参与序列化,所以为初始值
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }
}
实现一次多个对象序列化
  • 用一个ArrayList集合存储多个对象,然后直接对集合进行序列化即可
  • ArrayList集合已经实现了序列化接口

Student.java

package Demo;
import java.io.Serializable;

// 注意:对象如果需要序列化,必须实现序列化接口
public class Student implements Serializable {
    
    
    private String name;
    private int age;
    // private double score;
    // transient 修饰,则这个成员变量将不参与序列化(因为有的时候,其实不想要某个属性展示的,例如密码)
    private transient double score;

    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 double getScore() {
    
    
        return score;
    }

    public void setScore(double score) {
    
    
        this.score = score;
    }

    public Student() {
    
    
    }

    public Student(String name, int age, double score) {
    
    
        this.name = name;
        this.age = age;
        this.score = score;
    }

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

写入到磁盘

import Demo.Student;
import java.io.*;
import java.util.ArrayList;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Student zs = new Student("张三", 25, 100.00);
        Student ls = new Student("李四", 26, 100.00);
        ArrayList<Student> students = new ArrayList<>();
        students.add(zs);
        students.add(ls);

        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                OutputStream fos = new FileOutputStream(f);
                // 我们要写入对象,就需要用到对象序列化流
                ObjectOutputStream ois = new ObjectOutputStream(fos);
        ) {
    
    
            // 把整个ArrayList集合对象写进去,方便我们遍历集合去读
            ois.writeObject(students);
        } catch (IOException e) {
    
    
            throw new RuntimeException(e);
        }
    }
}

读取磁盘

import Demo.Student;
import java.io.*;
import java.util.ArrayList;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        File f = new File("D:\\Idea\\Codeing\\Day01\\src\\test.txt");
        try(
                InputStream fis = new FileInputStream(f);
                // 我们想要读取存储在文件中的对象,就需要对象反序列化
                ObjectInputStream ois = new ObjectInputStream(fis);
        ) {
    
    
            ArrayList<Student> students = (ArrayList<Student>) ois.readObject();
            System.out.println(students); // [Student{name='张三', age=25, score=0.0}, Student{name='李四', age=26, score=0.0}]
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }
}

IO框架

  • 框架就是解决某类问题,编写的一套类,接口等,可以理解成一个半成品,大多数框架都是第三方研发的

形式:

一般都是把类,接口等编译成class形式,再压缩成一个.jar结尾的文件发行出去

IO框架封装了Java提供的对文件,数据进行操作的代码,对外提供了更简单的方式来对文件进行操作,对数据进行读写等

Commons-io
  • apache开源基金组织提供的一组有关IO操作的小框架,目的是提高IO流的开发效率

FileUtils类

FileUtils类提供的部分方法展示 说明
public static void copyFile(File srcFile,File destFile) 复制文件
public static void copyDirectory(File srcDir,File destDir) 复制文件夹
public static void deleteDirectory(File directory) 删除文件夹
public static String readFileToString(File file,String encoding) 读数据
public static void writeStringToFile(File file,String data,String charname,boolean append) write data
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.charset.Charset;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        // FileUtils
        try {
    
    
            // 拷贝文件
            FileUtils.copyFile(new File("D:\\Idea\\Codeing\\Day01\\src\\in.txt"),new File("D:\\Idea\\Codeing\\Day01\\src\\out.txt"));
            // 拷贝文件夹
            FileUtils.copyDirectory(new File("C:\\Users\\huihui\\Desktop\\in"),new File("C:\\Users\\huihui\\Desktop\\out"));
            // 删除文件夹(非空的也可以)
            FileUtils.deleteDirectory(new File("C:\\Users\\huihui\\Desktop\\out"));
            // 读数据
            String s = FileUtils.readFileToString(new File("D:\\Idea\\Codeing\\Day01\\src\\in.txt"));
            System.out.println(s); // 111 不推荐使用这个了
            // 写数据 不推荐使用这个了
            FileUtils.writeStringToFile(new File("D:\\Idea\\Codeing\\Day01\\src\\in.txt"), "添加进去");
            // 追加数据
            FileUtils.writeStringToFile(new File("D:\\Idea\\Codeing\\Day01\\src\\in.txt"),"追加的数据", Charset.forName("UTF-8"),true);
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }
}

IOUtils class

Display of some methods provided by the IOUtils class illustrate
public static int copy(InputStream inputStream,outputStream outputStream) Copy files
public static int copy(Reader reader,Writer writer) Copy files
public static void write(String data,OutputStream output,String charsetName) write data

ActuallyJavaNatively also provides some one-line code processing for file manipulation (but none of them succeeded, I don’t know why)

import java.nio.file.Files;
import java.nio.file.Path;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        try {
    
    
            // 拷贝文件
            // Files.copy(Path.of("Day01\\src\\in.txt"),Path.of("Day01\\src\\out.txt"));
            // 读文件
            // System.out.println(Files.readString(Path.of("Day01\\\\src\\\\in.txt"))); //
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }
}

Guess you like

Origin blog.csdn.net/qq_52845451/article/details/133978940