文件和IO

这篇博客详细介绍了Java中File类的使用,包括文件和目录的抽象表示、构造方法、创建、判断、获取和删除功能。同时,文章还深入探讨了字节流和字符流的概念,包括字节流的写数据、字符流的编码解码问题,以及特殊操作如标准输入输出流、打印流和对象序列化。通过实例代码展示了各个操作的实现,是学习Java IO的实用参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package Demo;

import java.io.*;
import java.util.Properties;
import java.util.Set;




class Demo94 {
    public static void main(String[] args) throws IOException {
        stroe();
        load();
    }

    private static void load() throws IOException {
        Properties properties = new Properties();
        FileReader fr = new FileReader("Previous\\1.java");
//        void   load(Reader reader):从文件到集合
        properties.load(fr);
        System.out.println(properties);
        fr.close();

    }

    private static void stroe() throws IOException {
        //创建Properties集合
        Properties properties = new Properties();

        //创建FileWriter对象
        FileWriter fw = new FileWriter("Previous\\1.java");
        //往集合中添加元素
        properties.setProperty("heima001", "林黛玉");
        properties.setProperty("heima002", "王祖贤");
        properties.setProperty("heima003", "孙悟空");

        //void   store(Writer writer, String comments)//描述comments
        //从集合到文件
        properties.store(fw, null);
        fw.close();
    }

}

 

思维导图:

如果想看的下,可以把照片保存在本地,放大了跟方便看

 提示:一般本人学习新知识,都会做笔记和导图,笔记存在的目的方便加深记忆,思维导图存在的目的是加深知识的联系,让每个独立的知识点变得系统化

以下是我的笔记了

1.File

1.1.File概述和构造方法


 1.定义:文件和目录名的抽象表示

          重点:要区分什么是文件什么是目录  

                      文件就是比如我们创建的txt,word文档  目录就是文件夹      

 2.构造方法         


 1.2.File类的创建功能

     

package Demo;

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

public class Demo50 {
    public static void main(String[] args) throws IOException {
        //需求1:我要在E:\\a1目录下创建 java. txt
        File f=new File("D:\\a1\\java.txt");
        System.out.println(f.createNewFile());
        System.out.println("------------------");
        //第一次输出为true 第二次输出为flase
        //如果没有这个文件则创建 并返回true
        //如果有这个文件,则返回false

        //需求2:我要在E:\\a1目录下创建一个目录 Javase
        File f1=new File("D:\\a1\\javase");
        System.out.println(f1.mkdir());
        //创建目录(文件夹)

        //需求3:我要在E:\\a1目录下创建一个多级目录 JavaWeB\\HTML
        File f2=new File("D:\\a1\\JavaWeB\\HTML");
        System.out.println(f2.mkdir());
        //输出为false 原因:没有先创建JavaWeb这个目录,需使用mkdirs方法
        System.out.println(f2.mkdirs());
        //JAavWeb和HTML都创建成功 自己补齐父目录

        //需求4:我要在E:\\a1目录下创建一个文件Javase.txt
        File f3=new File("D:\\a1\\Javase.txt");
        System.out.println(f3.mkdir());
        //Javase.txt 看似是个文件名 但看创建文件还是目录看的是方法 而不是文件名
        System.out.println(f3.createNewFile());
        //false 因为目录和文件同名了 所以会直接输出false

    }
}

1.3.File类的判断和获取功能

1.判断方法

2.获取方法

 3.代码演示

package Demo;

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


class Demo51 {
    public static void main(String[] args) {
        File f = new File("C:\\Users\\天下第一剑\\com.team\\src\\Demo\\Demo.java");
        //测试此抽象路径名表示的File是否为 目录
        System.out.println(f.isDirectory());//emo.java是文件,不是文件夹,返回为false
        //测试此抽象路径名表示的File是否为 文件
        System.out.println(f.isFile());//true
        //测试此抽象路径名表示的File是否 存在
        System.out.println(f.exists());//存在返回为true

        System.out.println("---------------------------");
        //返回此抽象路径名的 绝对路径 名字符串
        System.out.println(f.getAbsolutePath());
        //C:\Users\天下第一剑\com.team\src\Demo\Demo.java


        //将此抽象路径名转换为 路径名字符串
        System.out.println(f.getPath());
        //C:\Users\天下第一剑\com.team\src\Demo\Demo.java
        System.out.println(f.getName());
        //Demo.java
        System.out.println("-------------------------------");

        File f1 = new File("D:\\a1");

        //public   String[ ] list():返回此抽象路径名表示的目录中的文件和目录的名称 字符串数组

        String[] strArray = f1.list();
        for (String s : strArray) {
            System.out.print(s + "\t");
        }
        //itheima.txt	java.txt	javase	Javase.txt	JavaWeB
        System.out.println();

        //返回此抽象路径名表示的目录中的文件和目录的 File对象数组
        File[] files = f1.listFiles();
        for (File file : files) {

            System.out.print(file + "\t");
            //D:\a1\itheima.txt	D:\a1\java.txt	D:\a1\javase	D:\a1\Javase.txt	D:\a1\JavaWeB

            System.out.print(file.getName() + "\t");
            //itheima.txt	java.txt	javase	Javase.txt	JavaWeB

            if (file.isFile()) {
                System.out.println(file.getName());//java.txt
            }
        }

    }
}

1.4.File类的删除功能

1.方法分类

 2.绝对路径和相对路径的区别

 3.代码演示

package Demo;

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

class Demo52{
    public static void main(String[] args) throws IOException {

        File f=new File("C:\\Users\\天下第一剑\\com.team\\src\\java.java");
        System.out.println(f.createNewFile());

        //在当前目录下创建java.txt文件
//        File f1=new File("com.team\\java.txt");
//        System.out.println(f1.createNewFile());
//        报错:IOException: 系统找不到指定的路径。

        //删除java.java文件
        System.out.println(f.delete());
        //删除java.java文件并且返回true

        //需求3:在当前模块目录下创建 itcast目录(可以用相对路径进行操作,但一直报错IOException: 系统找不到指定的路径。)
        File f1=new File("C:\\Users\\天下第一剑\\com.team\\itcast");
        System.out.println(f1.mkdir());

        //需求4:删除当前模块目录下的itcast目录
        System.out.println(f1.delete());
        //删除itcast目录 并且返回true
        System.out.println("------------------------------------------");

        //需求5:在当前模块下创建一个目录itcast,然后在该目录下创建一个文件java.txt
        File f2=new File("C:\\Users\\天下第一剑\\com.team\\itcast");
        System.out.println(f2.mkdir());
        File f3=new File("C:\\Users\\天下第一剑\\com.team\\itcast\\java.txt");
        System.out.println(f3.createNewFile());

        //需求6:刪除当前模块下的目录itcast(注意先后顺序)
        System.out.println(f2.delete());//false 要先删除目录下的文件 然后在删除目录
        System.out.println(f3.delete());
        System.out.println(f2.delete());
    }
}

2.字节流

2.1.IO流的概述和分类

1.IO流概述

 2.IO流分类

2.2.字节流写数据

1.字节流抽象类

 2.字节流写数据的步骤

 3.代码演示

class Demo53{
    public static void main(String[] args) throws IOException {
        //创建字节输出流对象
        FileOutputStream fos=new FileOutputStream("C:\\Users\\天下第一剑\\com.team\\fos.txt");
        /*
            1.字节输出流:调用系统创建文件
            2.创建字节输出流对象
            3.让字节输出流对象指向创建好的文件
         */
        // void write(int b):将指定的字节写入此文件输出流
        fos.write(97); //整数97对应写在fos.txt文件中字符a 
        fos.write(57); //整数57对应写在fos.txt文件中字符9
        fos.write(55); //整数55对应写在fos.txt文件中字符7 
        
        //最后都要释放资源
        //void  close():关闭此文件输出流并释放与此流相关联的任何系统资源
        fos.close()
    }
}

2.3.字节流写数据的三种方法

class Demo54{
    public static void main(String[] args) throws IOException {
        //构造方法:
        //FileOutputStream(String  name):创建文件输出流以指定的名称写入文件
        FileOutputStream fos=new FileOutputStream("C:\\Users\\天下第一剑\\com.team\\src\\java.txt");

        //FileOutputStream(File file):创建文件输出流已指定的 File对象文件
        File file=new File("C:\\Users\\天下第一剑\\com.team\\src\\java1.txt");
        FileOutputStream fos1=new FileOutputStream("C:\\Users\\天下第一剑\\com.team\\src\\java1.txt");

        //void write(int b):将指定的字节写入文件输出流
        fos.write(97);
        fos.write(98);
        fos.write(99);
        fos.write(100);
        fos.write(101);
        //输出:abcde

        //void write(byte[] b):将b.length()字节从指定的字节数组写入此文件输出流
        byte[] bytes={97,98,99,100,101};
        fos.write(bytes);
        //输出:abcde

        
        
        //byte[] getBytes():返回字符串对应的 字节数组
        byte[] bytes1 = "12345".getBytes();
        fos.write(bytes1);
        //12345

        
        
        
        //void write(byte[] b,int off,int len)
        // 将len字节从指定的字节数组开始,从off开始写入文件输出流,长度为len
        fos.write(bytes1,1,3);
        //234
        fos.close();
    }
}

2.4.字节流写数据的两个问题

1.换行

class Demo55{
    public static void main(String[] args) throws IOException {
        
        FileOutputStream fos=new FileOutputStream("C:\\Users\\天下第一剑\\com.team\\src\\java1");
        //写数据(换行)
        for (int i = 0; i <10 ; i++) {
            //getBytes直接返回对应的字符
            fos.write("hello".getBytes());
            fos.write("\n".getBytes());
        }
        //释放资源
        fos.close();

    }
}

2.追加

 

class Demo55{
    public static void main(String[] args) throws IOException {
        //FileOutputStream(File file, boolean append)
        //创建文件输出流以写入由指定的 File对象表示的文件(可连续输入)
        FileOutputStream fos=new FileOutputStream("C:\\Users\\天下第一剑\\com.team\\src\\java1",true);
        //写数据(换行)
        for (int i = 0; i <10 ; i++) {
            fos.write("hello".getBytes());
            fos.write("\n".getBytes());
        }
        //释放资源
        fos.close();
    }
}

2.5.字节流写数据的异常处理

class Demo56 {
    public static void main(String[] args) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream("F:\\Users\\天下第一剑\\com.team\\src\\java1");
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                fos.close();
            } catch (IOException e) {
                e.getMessage();
            }
        }
    }
}

2.6.字节流读数据(一次读一个字节)

1.概念

 2.代码演示

class Demo57 {
    public static void main(String[] args) throws IOException {
        //创建字节输入流对象
        //FileInputStream(String name)
        FileInputStream fis = new FileInputStream("C:\\Users\\天下第一剑\\com.team\\src\\java1");

        //调用字节输入流对象的读数据方法
        //int read():从该输入流读取一个字节的数据

        //java1的文件ab
        //第一次读取数据
        int by;
//        by = fis.read();
//        System.out.println(by);//97
//        System.out.println((char) by);//a
//
//        //第二次读取数据
//        by = fis.read();
//        System.out.println(by);//98
//        System.out.println((char) by);//b
//
//        //第三次读取数据
//        by = fis.read();
//        System.out.println(by);//-1
//        System.out.println((char) by);//

        //如果达到文件末尾为-1
//        by = fis.read();
//        while (by != -1) {
//            System.out.println((char) by);
//            by = fis.read();
//        }
        /*
            fis.read():读数据
            by=fis.read():把读取到的数据复制给by
            by!=-1:判断读取到的数据是否为-1
         */
        while((by=fis.read())!=-1){
            System.out.println(by);//97 98
            System.out.println((char) by);
        	//加不加ln可以实现输出字符串的功能
            //abc
			//fa
			//fawer
			//换行是根据文件里面的内容来的
        }
        fis.close();
    }
}

2.7.字符缓冲流

1.定义

2.构造方法

 3.思考

class Demo71 {
    public static void main(String[] args) throws IOException {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("Previous\\abc.txt"));
        //写数据
        bos.write("hello\r\n".getBytes());
        bos.write("world\r\n".getBytes());

        //字节输入流
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("Previous\\abc.txt"));
        int len;
        byte[] bytes = new byte[1024];
        while ((len = bis.read(bytes)) != -1) {
            //输出数据
            System.out.println(new String(bytes, 0, len));
       
        
        }
        //释放资源
        bos.close();
        bis.close();
    }
}

3.字符流

3.1.为什么会出现字符流

1.汉字存储

 2.原因

 3.代码演示

class Demo73 {
    public static void main(String[] args) throws IOException {
//        FileInputStream fis = new FileInputStream("Previous\\abc.txt");
//        FileOutputStream fos = new FileOutputStream("Previous\\123.txt");
//        int by;
//        while ((by = fis.read()) != -1) {
//            System.out.print((char) by);//é»ç£
//            fos.write(by);//先读写 后组成中文(以中文状态显示)
//        }
//        fis.close();
        String s1 = "abc";
        String s2 = "中国";
        byte[] byte1s = s1.getBytes();
        byte[] byte2s = s2.getBytes("UTF-8");//IDE默认
        byte[] byte3s = s2.getBytes("GBK");
        System.out.println(byte1s);//数组地址值:[B@776ec8df
        System.out.println(Arrays.toString(byte1s));//[97, 98, 99]
        System.out.println(Arrays.toString(byte2s));
        //[-28, -72, -83, -27, -101, -67] 负数都是表示中文(UTF-8)
        System.out.println(Arrays.toString(byte3s));
        //[-42, -48, -71, -6]
    }
}

3.2.编码表

1.基本知识

 2.字符集

 3.ASCII字符集

 4.GBXXXF字符集

 5.Unicode字符集

 6.小结

        采用何种规则编码,就要采用对应规则解码,否则就会出现乱码

3.3.字符中的编码和解码问题

1.编码

2.解码

3.代码演示

class Demo74 {
    public static void main(String[] args) throws UnsupportedEncodingException {
        //定义一个字符串
        String s = "中国";
        //默认编码
        byte[] bytes = s.getBytes();
        //默认编码 UTF-8
        //[-28, -72, -83, -27, -101, -67]
        System.out.println(Arrays.toString(bytes));
        // String( byte[] bytes):
        String ss = new String(bytes);//中国
        String sss = new String(bytes, "GBK");

        System.out.println(ss);
        System.out.println(sss);//编码是UTF-8 解码是GBK 出现乱码:涓浗
    }
}

3.4.字符流中的编码解码问题(关键)

1.字符抽象基类

2.代码演示

class Demo75 {
    public static void main(String[] args) throws IOException {
//        OutputStreamWriter ops = new OutputStreamWriter(new FileOutputStream("Previous\\123.txt"));
        OutputStreamWriter ops = new OutputStreamWriter(new FileOutputStream("Previous\\123.txt"), "GBK");
        InputStreamReader ips = new InputStreamReader(new FileInputStream("Previous\\123.txt"), "GBK");
        //���� 文本格式为UTF-8形式 输入的为GBK形式 通过字符输入流和字符输出流的一致编码解码来解决乱码情况
        ops.write("黄磊");
        ops.close();//字符输出流的结束位置!!!
        int by;
        while ((by = ips.read()) != -1) {
            System.out.print((char) by);
        }
        //123.txt写入黄磊

        ips.close();
    }
}

3.5.字符流写数据的5种方式(刷新和结束方法及其重要)

1.写数据方法

2.刷新和关闭方法

 

class Demo76 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("Previous\\1.txt"));
        //写一个字符
        osw.write(97);
        osw.flush();//刷新一下才能显示

        //写一个数组
        char[] strArray = {'a', 'b', 'c', 'd'};
        osw.write("\n");
        osw.write(strArray);
        osw.flush();

        //写一个字符数组的一部分
        osw.write("\n");
        osw.write(strArray, 0, strArray.length);
        osw.write(strArray, 1, 3);

        //写一个字符串
        osw.write("\n");
        osw.write("abcde");

        osw.close();//先刷新,后关闭
    }
}

3.6.字符流读数据

1.方法分类

 2.代码演示

class Demo77 {
    public static void main(String[] args) throws IOException {
        InputStreamReader ips = new InputStreamReader(new FileInputStream("Previous\\1.txt"));

        //一次读一个字符数据
//        int by;
//        while ((by = ips.read()) != -1) {
//            System.out.print((char) by);
//            //hello
//            //world
//            //java
//        }
        //相当于指针 已经指向了末尾 下面就不会在输出了
        //一次读一个字符数组数据
//        byte[] chs = new byte[1024];
//        注意byte是字节类型 要定义字符类型,这样的写法有问题
        char[] chs = new char[1024];
        int len;
        while ((len = ips.read(chs)) != -1) {
            System.out.println(new String(chs, 0, len));
            System.out.println();
            //hello
            //world
            //java
            System.out.println(chs);//字符数组里面的空格也会打印
        }
        ips.close();
    }
}

3.7.字符缓冲流

1.定义

 2.构造方法

 3.代码演示

public class Demo80_89 {
    public static void main(String[] args) throws IOException {
        //字符缓冲流
        BufferedReader br = new BufferedReader(new FileReader("Previous\\123.java"));
        BufferedWriter bw = new BufferedWriter(new FileWriter("Previous\\1.java"));

//        int by;
//        while((by=br.read())!=-1){
//            bw.write(by);
//        }
        char[] chs = new char[1024];
        int len;
        while ((len = br.read(chs)) != -1) {
            bw.write(chs, 0, len);
        }
        
        //打印
        char[] chs1 = new char[1024];
        int len1;
        while ((len1 = br.read(chs1)) != -1) {
            System.out.println(new String(chs1, 0, len1));
        }
        br.close();
        bw.close();
    }
}

 3.8.字符缓冲流特有功能

class Demo80 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("Previous\\123.java"));
        BufferedReader br = new BufferedReader(new FileReader("Previous\\123.java"));

        for (int i = 1; i <= 10; i++) {
            bw.write("hello" + i);
            bw.newLine();
            bw.flush();//刷新及其重要
        }
        String line;
        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }
        br.close();
        bw.close();
    }
}

3.9.IO流小结

 

 3.10.复制文件的异常处理

class Demo91 {
    public static void main(String[] args) {
        try (FileReader fr = new FileReader("fr.txt");
             FileWriter fw = new FileWriter("fw.txt")) {
            char[] chs = new char[1024];
            int len;
            while ((len = fr.read(chs)) != -1) {
                fw.write(chs, 0, len);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        //自动释放资源
    }
}

4.特殊操作

4.1.标准输入输出流(个人觉得不经常用)

1.输入流

 2.输出流

4.2.打印流

1.字节打印流

 2.字符打印流

 

4.3对象序列化流&对象反序列化流

1.对象序列化流:ObjectOutputStream

        1.介绍

 

        2.构造方法&对象序列化方法

         3.注意事项

        4.代码演示

package Demo3;

import java.io.Serializable;

/**
 * @auther 黄磊
 * @2021/8/24 14:39
 **/
public class Student implements Serializable {
    private String name;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
package Demo3;

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

/**
 * @auther 黄磊
 * @2021/8/24 14:37
 **/
public class ObjectOutputStreamDemo {
    public static void main(String[] args) throws IOException {
        //创建对象序列化流
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Previous\\123.txt"));
        //创建对象
        Student s = new Student("林青霞", 30);
        //void writeObject(Object obj):将指定的对象写入ObjectOutputStream
        oos.writeObject(s);
        //释放资源
        oos.close();
        //文件内容为乱码,需对象反序列化流来解决
        //�� sr
        //Demo3.Student��x�/� I ageL namet Ljava/lang/String;xp   t 	林青霞
    }
}

2.对象反序列化流 ObjectInputStrem

        1.概念&构造&反序列化方法

         2.代码演示

public class ObjectInputStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //创建对象反序列化流
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Previous\\123.txt"));

        //Object readObject():从ObjectInputStream中读取一个对象
        Object student = ois.readObject();
        Student s = (Student) student;
        System.out.println(s.getName() + "," + s.getAge());
        //林青霞30
    }
}

3.对象序列化的三个问题

        1.修改所属文件

    问题描述:用对象序列化一个对象后,修改所属类文件,读数据(不重写数据)会出现什么问题

 //新添加个toString方法,修改对象所属类文件
    //报错:InvalidClassException
    /*当序列化运行时检测到类中的以下问题之一时抛出。
        1.类的串行版本与从流中读取的类描述符的类型不匹配(这个)
        2.该类包含未知的数据类型
        3.该类没有可访问的无参数构造函数
    */

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
public class ObjectOutInputStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
//        write();//write()一下 则保存一个序列化id(根据Student类来的)
        read();
    }


    private static void write() throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Previous\\11.txt"));
        Student s = new Student("黄磊", 22);
        oos.writeObject(s);
        oos.close();
    }

    private static void read() throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("Previous\\11.txt"));
        Object o = ois.readObject();
        Student s = (Student) o;
        System.out.println(s.getName() + s.getAge());
        //黄磊22
        ois.close();
    }
}
//异常:InvalidClassException

        2.解决修改所属类文件出现的问题

public class Student implements Serializable {
    //如何解决InvalidClassException的问题
    //将序列号设置为常量
    private static final long serialVersionUID=42L;
    
    private String name;
    private int age;

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
  @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

        3.对象中的成员变量不想被序列化

 private static final long serialVersionUID=42L;
    private String name;
    //不被序列化  关键字transient
    private transient int  age;
    //黄磊0

 4.4.Properies

1.概叙

 2.特有方法

 

class Demo93 {
    public static void main(String[] args) {
        Properties properties = new Properties();
//        Object   setProperty(String key, String value),设置键和值都是String类型
        properties.setProperty("heima001", "林青霞");
        properties.setProperty("西游记", "孙悟空");
        properties.setProperty("红楼梦", "王熙凤");
//        String   getProperty(String key):由键获值
        System.out.println(properties.getProperty("heima001"));
        //林青霞
        System.out.println(properties.getProperty("水浒传"));
        //null
//        Set<String>   stringPropertyNames( ):获得键集
        Set<String> keys = properties.stringPropertyNames();
        for (String key : keys) {
            String value = properties.getProperty(key);
            System.out.println(key + "," + value);
            //红楼梦,王熙凤
            //西游记,孙悟空
            //heima001,林青霞
        }
    }
}

3.Properties和IO流相结合的方法

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值