学习java第20天

2020/8/21

1.Properties类

1.概述

Properties叫属性集,是Hashtable的子类,属于双列集合,这个集合键值对都是字符串类型,不需要规定泛型,我们通常使用与流相关的变量

2.构造函数

方法说明
public Properties创建一个空的属性列表

3.常用方法

方法说明
Object setProperty(String key,String value)添加键值对
String getProperty(String key)根据键获取值
stringPropertyNames()获取所有的键
load(输入流)把文件中的键值对数据读到集合中
store(输出流,String comments)把集合中的键值对保存到文件中
  • 专门存放键值对的文件· abc.properties

  • 键值对存放中间分隔符是等号或者冒号

  • 后缀位properties的文件是配置文件, #是注释

  • 集合相关方法

    import java.util.Properties;
    import java.util.Set;
    
    public class Test01 {
        public static void main(String[] args) {
            Properties p = new Properties();
    
            p.setProperty("username","柳岩");
            p.setProperty("password","123456");
    
            String s = p.getProperty("username");
            System.out.println(s);
    
            Set<String> set = p.stringPropertyNames();
            System.out.println(set);
        }
    }
    

在这里插入图片描述

  • 配置文件自己会进行检查,不允许重名

  • IO相关方法

    • 读数据

      import java.io.FileReader;
      import java.io.IOException;
      import java.util.Properties;
      
      public class Test03 {
          public static void main(String[] args) throws IOException {
              Properties p = new Properties();
              FileReader fr = new FileReader("day11\\abc.properties");
              //会把文件中的键值对读取到集合中
              p.load(fr);
              String font = p.getProperty("font");
              String color = p.getProperty("color");
      
              System.out.println("字体大小为:"+font);
              System.out.println("字体颜色为"+color);
          }
      }
      

在这里插入图片描述

  • 写数据

    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.Properties;
    
    public class Test02 {
        public static void main(String[] args) throws IOException {
            Properties p = new Properties();
    
            p.setProperty("font","16");
            p.setProperty("color","white");
    
            FileWriter fw = new FileWriter("day11\\abc.properties");
            //store() :把集合中的键值对写出到文件中
            //第一个参数输出流,第二个参数输出备注
            p.store(fw,"comments");
    
            fw.close();
        }
    }
    

在这里插入图片描述

2.ResourceBundle工具类

1.作用

  • 可以在某些情况下,替代·Properties完成读取键值对
    • 前提:
      • 文件必须是配置文件,以properties为后缀名
      • 文件必须放在src这个目录下

2.创建对象

  • 静态方法:

    // 使用指定的基本名称,默认语言环境和调用者的类加载器获取资源包。
    static ResourceBundle getBundle(String baseName);
    

3.获取方法

String getString(String key)//根据键获取值
  • 示例代码

    import java.io.FileReader;
    import java.io.IOException;
    import java.util.Properties;
    import java.util.ResourceBundle;
    import java.util.Set;
    
    public class Test04 {
        public static void main(String[] args) throws IOException {
            /*        Properties p = new Properties();
            FileReader fr = new FileReader("day11\\abc.properties");
            p.load(fr);
            Set<String> set = p.stringPropertyNames();
            for (String s : set) {
                String str = p.getProperty(s);
                System.out.println(s+"="+str);
            }*/
            ResourceBundle rb = ResourceBundle.getBundle("abc");
            String font = rb.getString("font");
            System.out.println(font);
            String color = rb.getString("color");
            System.out.println(color);
        }
    }
    

在这里插入图片描述

3.缓冲流

1.介绍

  • 缓冲功能就是提高效率

  • 普通流的使用效率比较低,java提供四个缓冲流提高四个普通流的效率

  • 字符串缓冲区、Stringbulider

  • 之前字符流有的方法缓冲流都有

  • 缓冲输出流都是先把数据输出到缓冲区

    FileOutputStream    -->  BufferedOutputStream
    FileInputStream     -->  BufferedInputStream
    FileWriter          -->  BufferedWriter
    FileReader          -->  BufferedReader
    

2.字节缓冲流

  • 构造方法

    public BufferedInputStream(InputStream in)    : 创建一个新的缓冲输入流。 
    public BufferedOutputStream(OutputStream out) : 创建一个新的缓冲输出流。
    
  • 缓冲效果显示

    • 字节缓冲流作用就只是提高效率,没有什么特殊功能。
    import java.io.*;
    
    public class Test05 {
        public static void main(String[] args) throws IOException {
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day11\\提醒.txt"));
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day11\\提醒.txt"));
            bis.close();
            bos.close();
        }
    }
    

3.字符缓冲流

  • 构造方法

    public BufferedReader(Reader in):创建一个新的缓冲输入流
    public BufferedWriter(Writer out):创建一个新的缓冲输出流
    
  • 方法演示

    • 之前字符流有的方法缓冲流都有
    public class Test06 {
        public static void main(String[] args) throws IOException {
            //public BufferedReader(Reader in)  :创建一个新的缓冲输入流。
            BufferedReader br = new BufferedReader(new FileReader("day11\\123.txt"));
    
    
            //public BufferedWriter(Writer out) : 创建一个新的缓冲输出流。
            BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\123.txt"));
    
            /*
            方法
                字符缓冲输入流
                    输入一个字符
                    输入一个字符数组
                字符缓冲输出流
                    输出一个字符
                    输出一个字符数组
                    输出一个字符数组的一部分
                    输出一个字符串
             */
            
        }
    }
    
  • 字符缓冲流中特有的方法

    • 两个特殊方法
    BuffeeredReader:
    	public String readLIine()://都一行文字
    							//读取一整行,如果读到了结尾返回null
    BufferedWriter:
    	public void newLine()//写换行,由系统属性定义符号
    							//兼容不同的系统
    
  • 示例代码

    • 读取一行
    import java.io.*;
    
    public class Test07 {
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new FileReader("day11\\提醒.txt"));
            String s = br.readLine();
            System.out.println(s);
            System.out.println(br.readLine());
            System.out.println(br.readLine());
            //如果读到了末尾 文件会返回null
            System.out.println(br.readLine());
            
            br.close();
        }
    }
    

在这里插入图片描述

  • 换行

    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    
    public class Test08 {
        public static void main(String[] args) throws IOException {
            BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\提醒.txt"));
            bw.write("加一行,");
            bw.write("看看换行吗?");
            bw.newLine();//换行
            bw.write("哈哈");
            bw.close();
        }
    }
    

在这里插入图片描述

  • 缓冲流的小结

    字节缓冲流	
        没有特殊的方法,只是提高了效率
    字符缓冲流
        第一个功能是提高效率
        特殊功能:
        	读取一整行readLine()
        	写出换行符newLine()
    
  • 练习题

    • 需求:排序
    • 排序前文件里面是乱序的,排序后,文件里面是123456789
    3.侍中、侍郎郭攸之、费祎、董允等,此皆良实,志虑忠纯,是以先帝简拔以遗陛下。愚以为宫中之事,事无大小,悉 以咨之,然后施行,必得裨补阙漏,有所广益。
    8.愿陛下托臣以讨贼兴复之效,不效,则治臣之罪,以告先帝之灵。若无兴德之言,则责攸之、祎、允等之慢,以彰其 咎;陛下亦宜自谋,以咨诹善道,察纳雅言,深追先帝遗诏,臣不胜受恩感激。
    4.将军向宠,性行淑均,晓畅军事,试用之于昔日,先帝称之曰能,是以众议举宠为督。愚以为营中之事,悉以咨之, 必能使行阵和睦,优劣得所。
    2.宫中府中,俱为一体,陟罚臧否,不宜异同。若有作奸犯科及为忠善者,宜付有司论其刑赏,以昭陛下平明之理,不 宜偏私,使内外异法也。
    1.先帝创业未半而中道崩殂,今天下三分,益州疲弊,此诚危急存亡之秋也。然侍卫之臣不懈于内,忠志之士忘身于外 者,盖追先帝之殊遇,欲报之于陛下也。诚宜开张圣听,以光先帝遗德,恢弘志士之气,不宜妄自菲薄,引喻失义,以 塞忠谏之路也。
    9.今当远离,临表涕零,不知所言。
    6.臣本布衣,躬耕于南阳,苟全性命于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣 以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间,尔来二十有一年矣。
    7.先帝知臣谨慎,故临崩寄臣以大事也。受命以来,夙夜忧叹,恐付托不效,以伤先帝之明,故五月渡泸,深入不毛。 今南方已定,兵甲已足,当奖率三军,北定中原,庶竭驽钝,攘除奸凶,兴复汉室,还于旧都。此臣所以报先帝而忠陛 下之职分也。至于斟酌损益,进尽忠言,则攸之、祎、允之任也。
    5.亲贤臣,远小人,此先汉所以兴隆也;亲小人,远贤臣,此后汉所以倾颓也。先帝在时,每与臣论此事,未尝不叹息 痛恨于桓、灵也。侍中、尚书、长史、参军,此悉贞良死节之臣,愿陛下亲之信之,则汉室之隆,可计日而待也。
    
  • 代码编写

    import java.io.*;
    import java.util.TreeSet;
    
    public class Test09 {
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new FileReader("day11\\出师表.txt"));
            TreeSet<String> set = new TreeSet<>();
            String s;
            while ((s = br.readLine()) != null) {
                set.add(s);
            }
            System.out.println(set);
            BufferedWriter bw = new BufferedWriter(new FileWriter("day11\\出师表.txt"));
            for (String s1 : set) {
                bw.write(s1);
                bw.newLine();
            }
            br.close();
            bw.close();
        }
    }
    

4.转换流

1.编码表介绍

在这里插入图片描述

2.输入转换流InputStreamReader类

  • 构造方法

    InputStreamReader(InputStream in) : 创建一个使用默认字符集的字符流。 
    InputStreamReader(InputStream in, String charsetName) : 创建一个指定字符集的字符流
    
  • 代码演示

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    public class Test10 {
        public static void main(String[] args) throws IOException {
            InputStreamReader isr = new InputStreamReader(new FileInputStream("day11\\出师表.txt"));
            int read = isr.read();
            System.out.println(read);
            System.out.println((char)read);
            int read2 = isr.read();
            System.out.println(read2);
            System.out.println((char)read2);
        }
    }
    

在这里插入图片描述

3.输出转换流OutputStreamWriter类

  • 构造方法

    OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。 
    OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流
    
  • 代码演示

    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    
    public class Test11 {
        public static void main(String[] args) throws IOException {
            OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day11\\出师表.txt"), "GBK");
            osw.write("中国");
            osw.close();
        }
    }
    

在这里插入图片描述

  • 总结

    转换流的本质也是字符流,所以可以调用字符流的方法
    
    转换流用于指定编码表的情况
    在idea上普通流不能指定码表,默认都是UTF-8
    

4.练习:把UTF-8文件转成GBK

把’'出师表.txt"UTF-8编码的文件 变成了 ‘’出师表2.txt‘’GBK编码的文件

import java.io.*;

public class Test12 {
    public static void main(String[] args) throws IOException {
        FileReader fr = new FileReader("day11\\出师表.txt");
        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day11\\出师表2.txt"),"GBK");
        int read ;
        while((read = fr.read())!=-1){
            osw.write(read);
        }
        fr.close();
        osw.close();
        InputStreamReader isr = new InputStreamReader(new FileInputStream("day11\\出师表2.txt"),"GBK");
        while ((read = isr.read())!=-1){
            System.out.print((char)read);
        }
        isr.close();
    }
}

5.序列流

1.概述

  • ​ 序列流可以操作对象。

  • ​ 序列化:把对象从内存保存到文件中。

  • ​ 反序列化:把对象从文件读取到内存中。

2.ObjectOutputStream类

  • 序列化流,对象输出流

  • 构造方法

    public ObjectOutputStream(OutputStream out) : 创建一个指定的ObjectOutputStream
    
  • 写出对象方法

    public final void writeObject (Object obj) : 将指定的对象写出。
    
  • 常见的两个疑惑

    • Serializable这个接口我们称为是标记型接口,这个接口中没有任何的方法。
    • 输出的对象在电脑中显示是乱码,这是正常的。因为电脑根本就没有查看对象的方式。
    • 序列化把对象保存在硬盘中
  • 代码演示

    import java.io.Serializable;
    
    public class Student implements Serializable{
        String name;
        int age;
    
        public Student() {
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    
    public class Test13 {
        public static void main(String[] args) throws IOException{
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\123.txt"));
            Student stu = new Student("柳岩", 36);
            oos.writeObject(stu);
            oos.close();
        }
    }
    

3.ObjectInputSream类

  • 反序列化流,对象输入流

  • 构造方法

    public ObjectInputStream(InputStream in) : 创建一个指定的ObjectInputStream
    
  • 读取对象方法

    public final Object readObject() : 读取一个对象。
    
  • 代码演示

    import java.io.*;
    
    public class Test14 {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\123.txt"));
            Object o = ois.readObject();
            Student stu = (Student)o;
            System.out.println(stu.toString());
            ois.close();
        }
    }
    

4.对象操作的作用

  • 对象操作流作用就是输出输入对象类型,别的流都是只能操作文本。

5.对象操作的小知识点

  • transient关键字

    • transient表示瞬态,被瞬态修饰的成员变量不会被序列化。

      private transient int age;
      
  • serialVersionUID问题

    • 每个类都有一个UID编号,每次修改类编号都会随机改变,如果类在序列化和反序列化之间编号不同,反序列化会失败。如果中间要修改这个类,需要在序列化之前手动指定一个UID.
import java.io.Serializable;

public class Student implements Serializable {
    public static final long serialVersionUID = 2134186281837358146L;
    String name;
    String sex;
    int age;

    public Student() {
    }

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

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

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

public class Test5_1 {
    public static void main(String[] args) throws IOException {
        Student stu = new Student("迪丽热巴","女",18);
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\test5_1.txt"));
        oos.writeObject(stu);
        oos.close();
    }
}

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

public class Test5_2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\test5_1.txt"));
        Object o = ois.readObject();
        Student s = (Student) o;
        System.out.println(s);
    }
}
  • 序列化多个对象

    • readObject()方法在读取到末尾的时候会直接抛出EOFException,不建议读取多次。
    • 如果想要保存多个对象,建议把多个对象放在一起一次保存(用集合存储)。
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.util.ArrayList;
    
    public class Test03 {
        public static void main(String[] args) throws IOException {
    
            //ObjectOutputStream序列化流,对象输出流
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("day11\\123.txt"));
    
            //创建对象
            Student s1 = new Student("柳岩",38);
            Student s2 = new Student("崔航",28);
    
            //放在集合中
            ArrayList<Student> list = new ArrayList<>();
            list.add(s1);
            list.add(s2);
    
            //输出任意类型对象
            oos.writeObject(list);
    
            //关流
            oos.close();
        }
    }
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.util.ArrayList;
    @SuppressWarnings("all")//带着泛型的转型都有警告,用此语句来消除
    public class Test04 {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
    
            //对象输入流
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("day11\\123.txt"));
            //读取对象
            Object obj = ois.readObject();
            //向下转型
            ArrayList<Student> list = (ArrayList<Student>)obj;
            //打印
            System.out.println(list);
            //关流
            ois.close();
        }
    }
    

6.打印流

1.概述

  • 打印流帮助程序把数据用打印的方式来输出。

2.构造方法

public PrintStream(String fileName) : 使用指定的文件名创建一个新的打印流。

3.代码演示

import java.io.FileNotFoundException;
import java.io.PrintStream;

public class Test01 {
    //打印流
    public static void main(String[] args) throws FileNotFoundException {

        //创建对象
        PrintStream ps = new PrintStream("day11\\123.txt");
        //输出
        //以打印的方式来输出,你写啥就是啥
        ps.print(97);
        ps.print(98);
        ps.print(1);
        ps.print(3.14);
        ps.print("哈哈哈");
        ps.println('a');
        ps.println('b');
        ps.println('c');

        //在控制台输出数据
        System.out.println();

        //输出语句使用ps这个对象作为打印流
        System.setOut(ps);

        System.out.println("柳岩");

        //关流
        ps.close();
    }
}

在这里插入图片描述

7.装饰设计模式

1.概述

如果想要对类进行增强,且不想使用继承的情况下。就可以使用装饰设计模式。

前提:
	被装饰类必须实现接口。

2.装饰设计模式写法

  1. 用装饰类实现和被装饰类同样的接口。

  2. 在装饰类中定义被装饰类的对象,使用构造方法传入对象。

  3. 需要增强的方法自己去编写。

  4. 不需要增强的方法调用被装饰类原来的方法。

3.代码演示

package com.itheima_05;

public interface Star {
    //唱跳
    void singAndDance();
    //rap
    void rap();
}

//被装饰类
public class CaiXuKun implements Star{
    //功能
    public void singAndDance(){
        System.out.println("唱跳");
    }

    public void rap(){
        System.out.println("鸡你太美~");
    }
}

//装饰类 增强类
public class BufferedCaiXuKun implements Star {
    //定义成员变量
    CaiXuKun cxk;
    //构造方法
    public BufferedCaiXuKun(CaiXuKun cxk) {
        this.cxk = cxk;
    }
    @Override
    //增强的方法
    public void singAndDance() {
        System.out.println("唱青藏高原");
        System.out.println("跳广场舞");
    }
    @Override
    public void rap() {
        cxk.rap();
    }
}

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

        //创建增强类对象
        BufferedCaiXuKun bc = new BufferedCaiXuKun(new CaiXuKun());

        //调用方法
        bc.rap();
        bc.singAndDance();
    }
}

4.开发的原则

开发的原则:
	高内聚,低耦合

	内聚:自己独立完成功能的能力。
	耦合:代码和代码之间的依赖。
	
	继承有一个缺点就是会提高类的耦合。

8.commons-io包

1.概述

commons-io是一个第三方jar包。

commons-io是Apache基金组织开发的开源工具,这个工具不在JDK里,使用的时候需要单独导入jar包。

2.使用方式

  1. 下载commons-io相关jar包;http://commons.apache.org/proper/commons-io/
  2. 把commons-io-2.6.jar包复制到指定的Module的lib目录中
  3. 将commons-io-2.6.jar加入到classpath【右键–add as Library–选择到模块中】

3.方法

  • IOUtils类中

    • public static int copy(InputStream in, OutputStream out) 文件复制(适合文件大小为2GB以下)
    • public static long copyLarge(InputStream in, OutputStream out) 文件复制(适合文件大小为2GB以上)
  • FileUtils类中

    • public static void copyFileToDirectory(final File srcFile, final File destFile) //复制文件到另外一个目录下
    • public static void copyDirectoryToDirectory( file1 , file2 );//复制file1目录到file2位置
    package com.itheima_06;
    
    import org.apache.commons.io.FileUtils;
    import org.apache.commons.io.IOUtils;
    
    import java.io.*;
    
    public class Test01 {
        public static void main(String[] args) throws IOException {
    
            //IOUtils
            //public static int copy(InputStream in, OutputStream out)      文件复制(适合文件大小为2GB以下)
    
            //IOUtils.copy(new FileInputStream("day11\\出师表.txt"),new FileOutputStream("C:\\Users\\jin\\Desktop\\出师表.txt"));
    
    
            //public static long copyLarge(InputStream in, OutputStream out) 文件复制(适合文件大小为2GB以上)
            //IOUtils.copyLarge(new FileInputStream("day11\\出师表.txt"),new FileOutputStream("C:\\Users\\jin\\Desktop\\出师表.txt"));
    
            //FileUtils
            //public static void copyFileToDirectory(final File srcFile, final File destFile) //复制文件到另外一个目录下
            //FileUtils.copyFileToDirectory(new File("C:\\Users\\jin\\Desktop\\1234.txt"),new File("C:\\Users\\jin\\Desktop\\day11"));
    
            //public static void copyDirectoryToDirectory( file1 , file2 );//复制file1目录到file2位置
            FileUtils.copyDirectoryToDirectory(new File("C:\\Users\\jin\\Desktop\\repositorys"),new File("C:\\Users\\jin\\Desktop\\day11"));
    
        }
    }
    

    其实我们现在所能想到的功能,都已经有人实现了。

    现阶段学习的很多知识点都是原理并不是应用。

9.IO流的异常处理

  • JDK7之前

    package com.itheima_06;
    import java.io.*;
    public class Test02 {
        public static void main(String[] args){
    
            OutputStreamWriter osw = null;
    
            try {
                //创建转换流对象
                osw = new OutputStreamWriter(new FileOutputStream("day11"), "GBK");
    
                //输出汉字
                osw.write("中国");
    
            }catch (IOException e){
    
            }finally {
                //一定会执行的代码
                try {
                    //关流
                    if(osw != null) {
                        osw.close();
                    }
                }catch (IOException e){
    
                }
            }
        }
    }
    
  • JDK7之后

    不需要调用关流方法

    try(创建流对象;创建流对象){
        其他代码
    }catch(异常类型 异常对象){
        
    }
    
    

不需要调用关流方法,这个写法代码会自动帮我们关流


```java
package com.itheima_06;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;

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

        //JDK7之后trycatch可以帮我们关流
        
        try(OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day11\\123.txt"),"GBK")){
            osw.write("中国");
        }catch (IOException e){
            //异常处理
        }
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值