Java10-I/O

https://www.nowcoder.com/tutorial/94/ae05554a3ad84e42b6f9fc4d52859dc4

https://how2j.cn/frontroute
https://how2j.cn/k/io/io-file/345.html

1 文件

1.1 创建

package14个程序_IO.a1_文件;

import java.io.File;

public class test {
    public static void main(String[] args) {
        File file1 = new File("d:/LOLFolder");
        System.out.println("file1 的绝对路径: " + file1.getAbsolutePath());

        File file2 = new File("LOL1.exe");
        System.out.println("file2 的绝对路径: " + file2.getAbsolutePath());

        // 把 file1 作为父目录创建文件对象
        File file3 = new File(file1,"LOL2.exe");
        System.out.println("file3 的绝对路径: " + file3.getAbsolutePath());
    }
}

1.2 常用方法

1

package14个程序_IO.a1_文件.常用方法1;

import java.io.File;
import java.util.Date;

public class test {
    public static void main(String[] args) {
        File file1 = new File("d:/LOLFolder/LOL.exe");
        System.out.println("当前文件是: " + file1);

        System.out.println("是否存在: " + file1.exists());
        System.out.println("是否是文件夹: " + file1.isDirectory());
        System.out.println("是否是文件: " + file1.isFile());
        System.out.println("长度 = " + file1.length());

        long time = file1.lastModified();
        Date d = new Date(time);
        System.out.println("获取文件最后的修改时间: " + d);

        //文件重命名
        File file2 = new File("d:/LOLFolder/DOTA.exe");
        file1.renameTo(file2);
        System.out.println("LOL.exe 改名为 DOTA.exe");

        // d:/LOLFolder 确实存在一个LOL.exe, 才可以看到对应的文件长度、修改时间等信息
    }
}

2

package14个程序_IO.a1_文件.常用方法2;

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

public class test {
    public static void main(String[] args) {
        File file = new File("D:/LOLFolder/skin/garen.ski");

        // 以字符串数组形式, 返回当前文件夹下所有文件(不包含子文件及子文件夹)
        file.list();

        // 以文件数组的形式,返回当前文件夹下的所有文件(不包含子文件及子文件夹)
        File[] files = file.listFiles();

        // 以字符串形式返回获取所在文件夹
        file.getParent();

        // 以文件形式返回获取所在文件夹
        file.getParentFile();

        // 创建文件夹,如果父文件夹skin不存在,创建就无效
        file.mkdir();

        // 创建文件夹,如果父文件夹skin不存在,就会创建父文件夹
        file.mkdirs();

        // 创建一个空文件,若父文件夹skin不存在,就会抛出异常
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 在创建一个空文件前,应该创建父目录
        file.getParentFile().mkdir();

        // 列出所有的盘符 c: d: e: 等
        file.listRoots();

        // 删除文件
        file.delete();

        // JVM结束时,删除文件。删除临时文件
        file.deleteOnExit();
    }
}

1.3 练习1

C:\WINDOWS
遍历该目录所有的文件(不用遍历子目录)
找出这些文件里,最大、最小(非0)的那个文件,打印出他们的文件名

package14个程序_IO.a1_文件.练习1;

import java.io.File;

public class test {
    public static void main(String[] args) {
        File file = new File("C:\\WINDOWS");
        File[] files = file.listFiles();
        String max="", min = "";
        long i = Long.MAX_VALUE, j = 0;
        for (File f : files){
            if(f.isFile()){
                if(f.length() == 0)
                    continue;
                if(f.length() < i){
                    i = f.length();
                    min = f.toString();
                }
                if(f.length() > j){
                    j = f.length();
                    max = f.toString();
                }
            }
        }
        System.out.println("最小的文件: " + min + ", 其大小是: " + i + " 字节");
        System.out.println("最大的文件: " + max + ", 其大小是: " + j + " 字节");
    }
}

2 流

2.1 简单程序

不同介质间,有数据交互,JAVA用流实现
数据源可以是文件、数据库、网络、程序

读取文件的数据到程序中,在程序的角度,叫做输入流
输入流: InputStream
输出流:OutputStream

package14个程序_IO.a2_流.s1_简单程序;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class test {
    public static void main(String[] args) {
        File file = new File(".//1.txt");
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}


没报错,因为打开的文件存在

2.2 字节流

接口:
InputStream 字节输入流
OutputStream 字节输出流
用于以字节的形式读取、写入数据

FileInputStream

2.2.1 读

fileInputStream.read(); 读一个字节
fileInputStream.read(byte[] all); 读全部字节

public class File3 {
	public static void main(String[] args) throws Exception {      //主方法
		File f = new File("d:\\filetest\\file.txt");	           //创建文件对象f
		FileInputStream fis = new FileInputStream(f);	           //获取文件对象f的输入流对象fis
		char ch;                                                   //定义字符变量ch
		for (int i = 0; i < f.length(); i++) {			           //通过循环实现文件的读取
			ch = (char) fis.read();
			System.out.print(ch);
		}
		fis.close();                                               //关闭输入流
	}
}
package14个程序_IO.a2_流.s2_字节流;

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

public class test {
    public static void main(String[] args) {
        try {
            File file = new File("src\\第14个程序_IO\\a2_流\\s2_字节流\\1.txt");
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] all = new byte[(int)file.length()];
            fileInputStream.read(all);
            for (byte b:all){
                System.out.println(b);
            }
            fileInputStream.close();
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.2.2 写数据

fileInputStream.write(); 写一个字节
fileInputStream.write(byte[] all); 写全部字节

import java.io.*;
public class File5 {
	public static void main(String[] args) throws Exception {	//主方法
		File f = new File("d:\\filetest\\file.txt");	//创建一个文件类对象f
		FileOutputStream fos = new FileOutputStream(f);	                //创建一个文件输出流对象fos
		for (int i = 'a'; i <= 'z'; i++) {   			                     //通过循环语句往f中写入数据
			fos.write(i);
		}
		fos.close();                       				//关闭输出流
	}
	
}
package14个程序_IO.a2_流.s2_字节流.写数据;

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

public class test {
    public static void main(String[] args) throws IOException {
        try {
            File file = new File("src\\第14个程序_IO\\a2_流\\s2_字节流\\写数据\\1.txt");
            byte data[] = {88, 89};
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(data);
            System.out.println("写入成功!");
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

2.2.3 练习1

写数据到文件中
要点:如何创建父文件夹?若父文件夹不存在,会抛出异常

package14个程序_IO.a2_流.s2_字节流.练习1;

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

public class test {
    public static void main(String[] args) {
        try {
            File file = new File("src\\第14个程序_IO\\a2_流\\s2_字节流\\练习1\\数据文件\\1.txt");
            byte[] bytes = new byte[]{88, 89, 90};
            File file1 = new File(file.getParent());
            if (file1.exists()){
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                fileOutputStream.write(bytes);
                fileOutputStream.close();
                System.out.println("写入成功!");
            }else {
                // 创建之前并不存在的父文件夹
                boolean flag = file1.mkdir();
                if(flag){
                    System.out.println("父文件夹创建成功!");
                    FileOutputStream fileOutputStream = new FileOutputStream(file);
                    fileOutputStream.write(bytes);
                    fileOutputStream.close();
                    System.out.println("写入成功!");
                }else {
                    System.out.println("父文件目录创建失败!");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


运行后:

2.2.4 练习2

有个大于 100k 的文件
以 100k 为单位,拆成多个子文件,以编号为文件名
再把拆分的文件合并为一个文件

package14个程序_IO.a2_流.s2_字节流.练习2;

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

public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s2_字节流\\练习2";
        String name = "\\三体Ⅲ死神永生.txt";
        String target = "\\拆分文件";
        try {
            boolean flag = (!new File(path+target).exists()) ? splitFile(path+name, path+target) : mergeFile(path+target);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    static boolean splitFile(String path, String target) throws IOException {
        File file = new File(path);
        int length = (int) file.length();
        byte[] bytes = new byte[length];
        FileInputStream fileInputStream = new FileInputStream(path);
        fileInputStream.read(bytes);
        fileInputStream.close();

        int c = length/(1024*100);
        for (int i = 1; i <= c; i++){
            File newfile = new File(target+"\\"+i+".txt");

            //若父文件目录不存在,则新建之
            if(!new File(newfile.getParent()).exists()){
                new File(newfile.getParent()).mkdir();
            }

            FileOutputStream fileOutputStream = new FileOutputStream(newfile);
            if(i < c){
                fileOutputStream.write(bytes, (i-1)*(1024*100),1024*100);
            }else if(i == c){
                fileOutputStream.write(bytes,(i-1)*(1024*100), length-(1024*100)*(i-1));
            }
            fileOutputStream.close();
        }
        System.out.println("文件拆分成功!");
        return true;
    }

    static boolean mergeFile(String path) throws IOException{
        File file = new File(path);
        File[] arrFiles = file.listFiles();
        File file1 = new File(path + "\\合并的文件.txt");
        for(int i = 0; i < arrFiles.length; i++){
            FileInputStream fileInputStream = new FileInputStream(path + "\\"+(i+1) + ".txt");
//            FileInputStream fileInputStream = new FileInputStream(arrFiles[i]);
            byte[] bytes = new byte[(int) arrFiles[i].length()];
            fileInputStream.read(bytes);

            // 文件末尾追加数据
            FileOutputStream fileOutputStream = new FileOutputStream(file1,true);
            fileOutputStream.write(bytes);

            fileInputStream.close();
            fileOutputStream.close();
        }

        System.out.println("文件合并成功!");
        return true;
    }
}

第1次运行是拆分文件:

第2次是合并文件(因为已经有了拆分的文件):

2.3 多字节流

FilterInputStream filter = new BufferedInputStream(InputStream);
FilterInputStream 两个子类:BufferedInputStream、DataInputStream
DataInputStream dis = new DataInputStream(InputStream);

BufferedInputStream的mark()和reset()用法

import java.io.*;

public class File7 {
	public static void main(String[] args) throws Exception {	//主方法
		//创建一个文件类对象f
		File f = new File("d:\\1.txt");
		//创建一个文件输入流对象fis,并且以f作为参数
		FileInputStream fis = new FileInputStream(f);
		//创建一个过滤输入流对象filter,并且以fis作为参数
		FilterInputStream filter = new BufferedInputStream(fis);
		//通过循环语句将f中的数据读出并输出
		for (int i = 0; i < f.length(); i++) {
			System.out.print((char)filter.read());
		}
		fis.close();                           				//关闭输入流对象
	}
}
public class File10 {
	public static void main(String[] args) throws Exception {   //主方法
		File f = new File("d:\\1.dat");    //创建一个文件类对象f
		//创建一个文件输入流对象fis,并且以f作为参数
		FileInputStream fis = new FileInputStream(f);
		//创建一个多字节输入流对象dis,并且以fis作为参数
		DataInputStream dis = new DataInputStream(fis);
		try {
			//使用dis对象从f中读取数据
			System.out.println(dis.readUTF());
		} catch (Exception e) {
		}
		dis.close();                            //关闭输入流
	}
}

FilterOutputStream filter = new FilterOutputStream(fos);
FilterOutputStream 两个子类:BufferedOutputStream、DataOutputStream
DataOutputStream dos = new DataOutputStream(fos);

public class File8 {
	public static void main(String[] args) throws Exception {	//主方法
		//创建一个文件类对象f
		File f = new File("d:\\1.txt");
		//创建一个文件输出流对象fos,并且以f作为参数
		FileOutputStream fos = new FileOutputStream(f);
		//创建一个过滤输出流对象filter,并且以fos作为参数
		FilterOutputStream filter = new FilterOutputStream(fos);
		//通过循环语句往f中写入数据
		for (int i = 'a'; i < 'z'; i++) {
			filter.write(i);
		}
		fos.close();                           					//关闭输出流
	}
}
public class File9 {
	public static void main(String[] args) throws Exception {	//主方法
		String st;                              			    //关于定义字符串对象st
		File f = new File("d:\\1.dat");       			        //创建一个文件类对象f
		//创建一个文件输出流对象fos,并且以f作为参数
		FileOutputStream fos = new FileOutputStream(f);
		//创建一个多字节输出流对象dos,并且以fos作为参数
		DataOutputStream dos = new DataOutputStream(fos);
		//使用dos对象将数据写入到f中
		try {
			dos.writeUTF("明天要下雨了。");
			dos.writeUTF("明天要下雨了。");
			dos.writeUTF("明天要下雨了。");
			dos.writeUTF("明天要下雨了。");
		} catch (Exception e) {
		}
		dos.close();                          				//关闭输出流
	}
}

综合

public class File11 {
	public void read(DataInputStream dis) {          //实现文件的读方法read
		//在类中创建age,maths,name,chinese和physical参数
		String name = "";
		int age = 0;
		float maths = 0;
		float english = 0;
		float chinese = 0;
		float physical = 0;
		try {
			//在read方法中,以多字节输入流对象作为参数,并且利用此对象读取数据
			name = dis.readUTF();
			age = dis.readInt();
			maths = dis.readFloat();
			english = dis.readFloat();
			chinese = dis.readFloat();
			physical = dis.readFloat();
		} catch (Exception e) {
		}
		//输出相应的值
		System.out.println("姓名:" + name);
		System.out.println("年龄:" + age);
		System.out.println("数学成绩:" + maths);
		System.out.println("英语成绩:" + english);
		System.out.println("语文成绩:" + chinese);
		System.out.println("物理成绩:" + physical);
	}
	//在write方法中,以多字节输出流对象作为参数,并且利用此对象写入数据
	public void write(String name, int age, float maths, float english,
			float chinese, float physical, DataOutputStream dos) {
		try {
			dos.writeUTF(name);
			dos.writeInt(age);
			dos.writeFloat(maths);
			dos.writeFloat(english);
			dos.writeFloat(chinese);
			dos.writeFloat(physical);
		} catch (Exception e) {
		}
	}
	public static void main(String[] args) throws Exception {   //主方法
		//创建文件类对象f2和f
		File11 f2 = new File11();
		File f = new File("d:\\1.dat");
		//创建文件输入流对象fis
		FileInputStream fis = new FileInputStream(f);
		//创建数据输入流对象dis
		DataInputStream dis = new DataInputStream(fis);
		//创建文件输出流对象fos
		FileOutputStream fos = new FileOutputStream(f);
		//创建数据输出流对象dos
		DataOutputStream dos = new DataOutputStream(fos);
		//在文件类对象中写入内容并将其内容读出来
		f2.write("王鹏", 30, 87, 88, 93, 100, dos);
		f2.read(dis);
		f2.write("张浩", 29, 90, 89, 93, 100, dos);
		f2.read(dis);
		f2.write("宋江", 33, 77, 80, 90, 80, dos);
		f2.read(dis);
		f2.write("李宇", 32, 92, 81, 83, 90, dos);
		f2.read(dis);
		f2.write("宋丹", 31, 81, 98, 100, 99, dos);
		f2.read(dis);
		//关闭输入和输出流
		dos.close();
		dis.close();
	}
}

2.3 关闭流

1 在 try 中关闭
若文件不存在,或读取时出现问题抛出异常,那就不会执行关闭流,存在资源占用隐患

2 在 finally 中关闭

public class TestStream {
    public static void main(String[] args) {
        File f = new File("d:/lol.txt");
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(f);
            byte[] all = new byte[(int) f.length()];
            fis.read(all);
            for (byte b : all) {
                System.out.println(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 在finally 里关闭流
            if (null != fis)
                try {
                    fis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }
}

3 在 try() 中关闭

public class TestStream {
    public static void main(String[] args) {
        File f = new File("d:/lol.txt");
        
        // 把流定义在try()里,try, catch, finally 结束时,会自动关闭
        try (FileInputStream fis = new FileInputStream(f)) {
            byte[] all = new byte[(int) f.length()];
            fis.read(all);
            for (byte b : all) {
                System.out.println(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.4 字符流

2.4.1 读数据

BufferedReader(Reader)
FileReader(File)

public class File13 {
	public static void main(String[] args) throws Exception {   //主方法
		File f = new File("d:\\", "2.txt");		//创建一个文件类对象f
		//创建一个输入流对象fis,并且以f作为参数
		FileInputStream fis = new FileInputStream(f);
		//创建一个字符输入流对象isr,并且以fis作为参数
		InputStreamReader isr = new InputStreamReader(fis);
		//创建一个带缓冲的输入流对象,利用此对象读取一行数据
		BufferedReader br = new BufferedReader(isr);
		//输出读取到的内容
		System.out.println(br.readLine());
		
	}
}
public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s4_字节流\\1.txt";
        File file = new File(path);
        try (FileReader fileReader = new FileReader(file)){
            char[] all = new char[(int) file.length()];
            fileReader.read(all);
            for (char b:all){
                System.out.println(b);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.4.2 写数据

BufferedWriter(OutputStreamWriter)
FileWriter(File)

BufferedWriter:
flush():强制吧缓冲区数据写入输出流
newline():写入换行

public class File15 {
	public static void main(String[] args) throws Exception { 	//主方法
		File f = new File("d:\\", "2.txt"); 	//创建一个文件类对象f
		//创建一个输出流对象fos,并且以f作为参数
		FileOutputStream fos = new FileOutputStream(f);
		//创建一个字符输出流对象osw,并且以fos作为参数
		OutputStreamWriter osw = new OutputStreamWriter(fos);
		//创建一个带缓冲的输出流对象bw,利用此对象写入数据
		BufferedWriter bw = new BufferedWriter(osw);
		//输出相应内容和空格
		bw.write("小王是一个好学生。");
		bw.newLine();
		bw.write("他也是一个好学生。");
		bw.newLine();
		bw.write("小明也是一个好学生。");
		bw.close();                           				//关闭输出流对象
	}
}

综合:

public class File16 {
	//在read1方法中,以带缓冲的输入流对象为参数,它主要是让这个输入流对象读取数据
	public void read1(BufferedReader br) {                 //实现文件的读方法read1
		try {
			System.out.println(br.readLine());	//以行方式读取
		} catch (Exception e) {
		}
	}
	//在write1方法中,以带缓冲的输出流对象为参数,它主要是让这个输出流对象
	//写入数据到f对象
	public void write1(String str, BufferedWriter bw) {      //实现文件的写方法write1
		if (str.length() > 5) {
			try {
				bw.write(str);
				bw.newLine();
				bw.flush();
			} catch (Exception e) {
			}
		} else if ((str.length()) < 5) {
			try {
				bw.write("输入有误!");
				bw.newLine();
				bw.flush();
			} catch (Exception e) {
			}
		}
	}
	public static void main(String[] args) throws Exception {	           //主方法
		File16 f2 = new File16();                  	//创建类file16对象f2
		File f = new File("d:\\", "2.txt");	//创建一个文件类对象f
		//创建一个文件输出流对象fos
		FileOutputStream fos = new FileOutputStream(f);
		//创建一个文件输入流对象fis
		FileInputStream fis = new FileInputStream(f);
		//创建一个多字节的输出流对象osw
		OutputStreamWriter osw = new OutputStreamWriter(fos);
		//创建一个多字节输入流对象isr
		InputStreamReader isr = new InputStreamReader(fis);
		//创建一个带有缓冲的输出流对象bw
		BufferedWriter bw = new BufferedWriter(osw);
		//创建一个带缓冲的输入流对象br
		BufferedReader br = new BufferedReader(isr);
		//通过bw将数据写入到f2中
		f2.write1("祖国是个大花园", bw);
		f2.write1("小明说是吗", bw);
		f2.write1("小张觉得小明说的没有错", bw);
		f2.write1("谢谢了", bw);
		//通过br从f2中将数据读出来
		f2.read1(br);
		f2.read1(br);
		f2.read1(br);
		f2.read1(br);
		//关闭对象br和bw
		br.close();
		bw.close();
	}
}
package14个程序_IO.a2_流.s4_字节流.写数据;

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

public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s4_字节流\\写数据\\1.txt";
        File file = new File(path);
        try (FileWriter fileWriter = new FileWriter(file)){
            String data = "123456789asdfgh";
            char[] c = data.toCharArray();
            fileWriter.write(c);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2.4.3 练习 - 问价加密、解密

文本文件(非二进制),包含ASCII码、中文字符,进行加密解密
保存到 encodedFile 文件

加密算法:

数字:
不是9,在原来的基础上加1,如5变成6, 3变成4
是9,变成0

字母字符:
非z,向右移动一个,比如d变成e, G变成H
是z,z->a, Z-A。
字符需要保留大小写

非字母字符 保留不变

package14个程序_IO.a2_流.s4_字节流.练习;

import java.io.*;

public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s4_字节流\\练习\\原文本.txt";
        String target = "src\\第14个程序_IO\\a2_流\\s4_字节流\\练习\\encodedFile.txt";
        encryption(path,target); //加密文件
        decrypt(path,target); //解密文件
    }

    // 加密操作
    static void encryption(String path, String target){
        System.out.println("尝试加密文件...");
        File file = new File(path);
        File file1 = new File(target);
        try (FileReader fileReader = new FileReader(file)){
            char[] all = new char[(int) file.length()];
            fileReader.read(all);

            try (FileWriter fileWriter = new FileWriter(file1,true)){
                fileWriter.write("原文件内容:\n");
                fileWriter.write(all);

                fileWriter.write("\n\n加密文件内容:\n");
                for (char b:all){
                    if((b >= '0' && b < '9') || (b >= 'a'&& b < 'z') || (b >= 'A' && b < 'Z') )
                        fileWriter.write(b+1);
                    else if(b == '9')
                        fileWriter.write('0');
                    else if (b == 'z')
                        fileWriter.write('a');
                    else if (b == 'Z')
                        fileWriter.write('A');
                    else
                        fileWriter.write(b);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("成功!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 解密操作
    static void decrypt(String path,String target){
        System.out.println("尝试解密文件...");
        File file = new File(path);
        File file1 = new File(target);
        try (FileReader fileReader = new FileReader(file)){
            char[] all = new char[(int) file.length()];
            fileReader.read(all);

            try (FileWriter fileWriter = new FileWriter(file1,true)){
                fileWriter.write("\n\n解密文件内容:\n");
                for (char b:all){
                    if((b > '0' && b <= '9') || (b > 'a'&& b <= 'z') || (b > 'A' && b <= 'Z') )
                        fileWriter.write(b-1);
                    else if(b == '0')
                        fileWriter.write('9');
                    else if (b == 'a')
                        fileWriter.write('z');
                    else if (b == 'A')
                        fileWriter.write('Z');
                    else
                        fileWriter.write(b);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("成功!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.5 中文问题

ISO-8859-1 ASCII 数字、西欧字母(ISO-8859-1 包含 ASCII)
GBK GB2312 BIG5 中文(GB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文)
UNICODE 统一码,万国码

2.5.1 读 FileInputStream

package14个程序_IO.a2_流.s5_中文问题..FileInputStream;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s5_中文问题\\读\\FileInputStream\\1.txt";
        File file = new File(path);
        try (FileInputStream fileInputStream = new FileInputStream(file)){
            byte[] all = new byte[(int) file.length()];
            fileInputStream.read(all);
            for (byte b : all){
                int i = b&0x000000ff;//取16进制的后两位
                System.out.println(i);
            }
            String string = new String(all,"UTF-8");
            System.out.println(string);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.5.2 读 FileReader

package14个程序_IO.a2_流.s5_中文问题..z2_FileReader;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;

public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s5_中文问题\\读\\z2_FileReader\\1.txt";
        File file = new File(path);
        System.out.println("默认编码方式: " + Charset.defaultCharset());

        try(FileReader fileReader = new FileReader(file)){
            char[] all = new char[(int) file.length()];
            fileReader.read(all);
            System.out.println("FileReader默认编码方式: " + Charset.defaultCharset() + "\n其读取字符是:");
            System.out.println(new String(all));

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.5.3 练习1

找出 E5 B1 8C 这3个十六进制对应UTF-8编码的汉字

package14个程序_IO.a2_流.s5_中文问题.练习1;

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

public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s5_中文问题\\练习1\\1.txt";
        File file = new File(path);
        try(FileWriter fileWriter = new FileWriter(file)){
            byte[] data = new byte[]{(byte)0xE5, (byte) 0xB1, (byte) 0x8C};
            String string = new String(data,"UTF-8");
            fileWriter.write(string);
        } catch (IOException e) {
            e.printStackTrace();
        }

        try (FileReader fileReader = new FileReader(file)){
            char[] all = new char[(int) file.length()];
            fileReader.read(all);
            System.out.println(new String(all));
        }catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.5.4 练习2 - 移除BOM

记事本根据 UTF-8 编码,保存汉字会在最前面生成标示符
这个标示符表示该文件是用 UTF-8 编码
找出这段标示符对应的十六进制,开发一个方法,自动去除这段标示符

package14个程序_IO.a2_流.s5_中文问题.练习2_去除BOM;

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

public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s5_中文问题\\练习2_去除BOM\\1.txt";
        File file  = new File(path);
        delete(file);
    }

    public static void delete(File file) {
        byte[] all = new byte[(int) file.length()];
        try (FileInputStream fileInputStream = new FileInputStream(file);){
            fileInputStream.read(all);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        String s1 = "";
        s1 = new String(all, StandardCharsets.UTF_8);

        char[] data = s1.toCharArray();
        int temp = (int)data[0];
        String temp1 = Integer.toHexString(temp);

        if(temp1.equals("feff")){
            char[] data2 = new char[data.length-1];
            for(int i = 1; i < data.length; i++){
                data2[i-1] = data[i];
            }
            s1 = new String(data2);
        }else {
            System.out.println("无 UTF-8 标志符 BOM!");
        }

        System.out.println(s1);
    }
}

2.6 缓存流

2.6.1 读数据 BufferedReader

BufferedReader 一行一行【读数据】

package14个程序_IO.a2_流.s6_缓存流.读数据;

import java.io.*;

public class test {
    public static <bufferedReader> void main(String[] args) throws IOException {
        String path = "src\\第14个程序_IO\\a2_流\\s6_缓存流\\读数据\\1.txt";
        File file = new File(path);

        try (
                FileReader fileReader = new FileReader(file);
                BufferedReader bufferedReader = new BufferedReader(fileReader);
             ) {
            while (true){
                String line = bufferedReader.readLine();
                if (line == null)
                    break;
                System.out.println(line);
            }
        }catch (IOException e){
            e.printStackTrace();
        }

    }
}

2.6.2 写数据 PrintWriter

PrintWriter 一行一行【写数据】

package14个程序_IO.a2_流.s6_缓存流.写数据;

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

public class test {
    public static void main(String[] args) throws IOException {
        String path = "src\\第14个程序_IO\\a2_流\\s6_缓存流\\写数据\\1.txt";
        File file = new File(path);

        try (
            FileWriter fileWriter = new FileWriter(file,true);
            PrintWriter printWriter = new PrintWriter(fileWriter);
        ){
            int flag = 1;
            if (file.length() == 0)
                flag = 0;

            printWriter.println("\n啊啊啊啊啊啊");
            printWriter.println("hehehehe");
            printWriter.println("呵呵呵呵");

            if (flag == 0)
                System.out.println("写入数据成功!");
            else
                System.out.println("追加数据成功!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


2.6.3 flush

flush:立即把数据写入到硬盘,不是等缓存满了才写

package14个程序_IO.a2_流.s6_缓存流.c3_flush;

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

public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s6_缓存流\\c3_flush\\1.txt";
        File file = new File(path);

        try(FileWriter fileWriter = new FileWriter(file,true)){
            fileWriter.write("kill!!!\n");
            fileWriter.flush();
            fileWriter.write("you!!!\n\n");
            fileWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

运行 2 遍后:

2.6.4 练习 - 移除注释

默认:一行要么是注释,要么是内容
如果注释在后面,或者是/**/风格的注释,暂不用处理

package14个程序_IO.a2_流.s6_缓存流.c4_练习_移除注释;

import java.io.*;

public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s6_缓存流\\c4_练习_移除注释\\1.txt";
        File file = new File(path);

        try(
            FileReader fileReader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
        ){
            String buffer;
            StringBuffer stringBuffer = new StringBuffer();
            while ( (buffer = bufferedReader.readLine()) != null){
                String[] s = buffer.split("/");// 分割字符
                if(s.length < 2){
                    stringBuffer.append(buffer+"\n");
                }
            }
            System.out.println(stringBuffer);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.7 数据流

DataInputStream:数据输入流
DataOutputStream:数据输出流

package14个程序_IO.a2_流.s7_数据流.c1_读写;

import java.io.*;

public class test {
    public static void main(String[] args) {
        write();
        read();
    }
    
    public static void read(){
        String path = "src\\第14个程序_IO\\a2_流\\s7_数据流\\c1_读写\\1.txt";
        File file = new File(path);

        try (
            FileInputStream fileInputStream = new FileInputStream(file);
            DataInputStream dataInputStream = new DataInputStream(fileInputStream);
        ){
            boolean b = dataInputStream.readBoolean();
            int i = dataInputStream.readInt();
            String string = dataInputStream.readUTF();

            System.out.println("取到布尔值: " + b);
            System.out.println("取到整数值: " + i);
            System.out.println("取到字符串: " + string);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void write(){
        String path = "src\\第14个程序_IO\\a2_流\\s7_数据流\\c1_读写\\1.txt";
        File file = new File(path);

        try(
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
        ){
            dataOutputStream.writeBoolean(true);
            dataOutputStream.writeInt(1231231);
            dataOutputStream.writeUTF("123 is good!");
            System.out.println("数据写入文件成功!");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.7.1 练习

向文件中写入两数字,然后把这两数字读出来

package14个程序_IO.a2_流.s7_数据流.练习;

import java.io.*;

public class test {
    public static void main(String[] args) {
        String path = "src\\第14个程序_IO\\a2_流\\s7_数据流\\练习\\1.txt";
        File file = new File(path);

        try (
            FileWriter fileWriter = new FileWriter(file);
            PrintWriter printWriter = new PrintWriter(fileWriter);
            FileReader fileReader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
        ){
            int x = 30, y = 40, z = 60;
            printWriter.println(x+ "@" + y + "@" + z) ;
            printWriter.flush();

            String string = bufferedReader.readLine();
            String[] data = string.split("@");
            int i = 1;
            for (String t:data){
                System.out.println("data[" + i + "] = " + t);
                i++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2.8 对象流

2.8.1 序列化对象 Serializable

package14个程序_IO.a2_流.s8_对象流.测试;

import java.io.Serializable;

public class Hero implements Serializable {
    private static final long serialVersionUID = 1L;
    public String name;
    public float hp;
}
package14个程序_IO.a2_流.s8_对象流.测试;

import java.io.*;

public class test {
    public static void main(String[] args) {
        Hero hero = new Hero();
        hero.name = "盖伦";
        hero.hp = 300;

        String path = "src\\第14个程序_IO\\a2_流\\s8_对象流\\测试\\1.txt";
        File file = new File(path);
        try(
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            FileInputStream fileInputStream = new FileInputStream(file);
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        ){
            objectOutputStream.writeObject(hero);
            Hero hero1 = (Hero) objectInputStream.readObject();
            System.out.println("2.name = " + hero1.name);
            System.out.println("2.hp = " + hero1.hp);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

2.8.2 练习

1 准备长度是10,类型是 Hero 的数组,用10个 Hero 对象初始化该数组
2 该数组序列化到一个文件 heros.lo
3 用 ObjectInputStream 读取该文件,并转换为 Hero 数组,验证该数组中的内容,是否和序列化之前一样

package14个程序_IO.a2_流.s8_对象流.练习;

import java.io.*;

public class test {
    public static void main(String[] args) {
        int capacity = 10;
        Hero[] heroes = new Hero[capacity];

        for (int i = 0 ; i < capacity; i++){
            heroes[i] = new Hero();
            heroes[i].name = "hero" + (i+1);
        }

        String path = "src\\第14个程序_IO\\a2_流\\s8_对象流\\练习\\1.txt";
        File file = new File(path);
        try(
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
            DataOutputStream dataOutputStream = new DataOutputStream(fileOutputStream);
            FileInputStream fileInputStream = new FileInputStream(file);
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            DataInputStream dataInputStream = new DataInputStream(fileInputStream);
        ){
            for (int i = 0; i < capacity; i++){
                objectOutputStream.writeObject(heroes[i]);
                dataOutputStream.writeUTF("\n");
            }
            Hero[] data = new Hero[capacity];
            for (int i = 0; i < capacity; i++){
                data[i] = (Hero) objectInputStream.readObject();
                String t = dataInputStream.readUTF();
                System.out.println("data[" + (i + 1) + "] = " + data[i].name);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

3 System.in

3.1 System.in 单个字符

package14个程序_IO.输入System.s1_单个字符;

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

public class test {
    public static void main(String[] args) throws IOException {
        try(InputStream inputStream = System.in;){
            while (true){
                int i = inputStream.read();
                System.out.println("输出: " + i);
            }
        }
    }
}

3.2 Scanner 字符串

一行一行的读取

package14个程序_IO.输入System.s2_字符串;

import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        while (true){
            String line = s.nextLine();
            System.out.println("line = " + line);
        }
    }
}

3.3 读数

package14个程序_IO.输入System.s3_读整数;

import java.util.Scanner;

public class test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (true){
            int i = scanner.nextInt();
            System.out.println("int = " + i);
            long l = scanner.nextLong();
            System.out.println("long = " + l);
            double d = scanner.nextDouble();
            System.out.println("double = " +d);
        }
    }
}

3.4 自动创建类

自动创建有1个属性的类文件。
通过控制台,获取类名、属性名称、属性类型,根据一个模板文件,自动创建这个类文件,为属性提供 setter、getter
如:

public class @class@ {
    public @type@ @property@;
    public @class@() {
    }
    public void set@Uproperty@(@type@  @property@){
        this.@property@ = @property@;
    }
      
    public @type@  get@Uproperty@(){
        return this.@property@;
    }
}
package14个程序_IO.输入System.s4_自动创建类;

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

public class test {
    public static void main(String[] args) throws IOException {
        String path = "src\\第14个程序_IO\\输入System\\s4_自动创建类\\module.txt";
        File file = new File(path);
        creat_module(file);
        creat_follow(file);
    }

    public static void creat_module(File file) throws IOException {
        try (
            FileWriter fileWriter = new FileWriter(file);
            PrintWriter printWriter = new PrintWriter(fileWriter);
        ){
            String str =
                "public class @class@ {\npublic @type@ @property@;\n public @class@() {\n" +
                "    }\n public void set@Uproperty@(@type@  @property@){\nthis.@property@ = @property@;}\n pub" +
                "lic @type@  get@Uproperty@(){\n" +
                "        return this.@property@;\n" +
                "    }\n}";
            printWriter.write(str);
            System.out.println("模板创作成功!");
        }
    }

    public static String[] getString(){
        String[] str = new String[3];
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入类的名字:");
        str[0] = scanner.next();

        System.out.println("输入属性类型:");
        str[1] = scanner.next();

        System.out.println("输入属性名称:");
        str[2] = scanner.next();
        return str;
    }

    public static void creat_follow(File file){
        String[] str = getString();
        String[] strs = new String[20];

        try(
            FileReader fileReader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
        ){
            int n = 0;
            while(true){
                String s = bufferedReader.readLine();
                if(s == null){
                    break;
                }
                if (s.length() != 0){
                    strs[n++] = s;
                }
            }

            char[] cc = str[2].toCharArray();
            cc[0] = Character.toUpperCase(cc[0]);
            String ss = new String(cc);
            for (int i = 0; i < strs.length; i++){
                if (strs[i] != null){
                    if (strs[i].length() != 0){
                        strs[i] = strs[i].replaceAll("@class@",str[0]);
                        strs[i] = strs[i].replaceAll("@type@",str[1]);
                        strs[i] = strs[i].replaceAll("@property@",str[2]);
                        strs[i] = strs[i].replaceAll("@Uproperty@",ss);
                    }else continue;
                }else break;
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        String path = "src\\第14个程序_IO\\输入System\\s4_自动创建类\\" + str[0] +".txt";
        File file1 = new File(path);
        try(
            FileWriter fileWriter = new FileWriter(file);
            PrintWriter printWriter = new PrintWriter(fileWriter);
        ){
            for (int i = 0; i < strs.length; i++){
                if (strs[i] != null){
                    if (strs[i].length() != 0){
                        printWriter.write(strs[i]);
                        printWriter.write("\n");
                    }else continue;
                }else break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4 总结

来源:
https://blog.csdn.net/hui1setouxiang/article/details/89434123

错误更正:
GBK:中文简体繁体和日文
GB2312:中文简体

5 练习

1 复制文件/夹

1 复制源文件 srcFile 到目标文件 destFile
2 把【源文件夹】下所有的文件 复制到【目标文件夹下】(包括子文件夹)

package14个程序_IO.综合练习.复制文件;

import java.io.*;

public class test {
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        String root = "src\\第14个程序_IO\\综合练习\\复制文件\\三体Ⅲ死神永生.txt";
        String dest = "src\\第14个程序_IO\\综合练习\\复制文件\\三体Ⅲ死神永生(备份).txt";
        copyFile(root, dest);
        long end = System.currentTimeMillis();
        System.out.println("文件复制完成!");
        System.out.println("用时 = " + (end - start) + "ms\n");

        String root1 = "src\\第14个程序_IO\\综合练习\\复制文件\\src";
        String dest2 = "src\\第14个程序_IO\\综合练习\\复制文件\\dest";
        copyFolder(root1, dest2);
    }

    //复制文件
    public static void copyFile(String src, String dest) throws IOException {
        File file1 = new File(src);
        File file2 = new File(dest);
        if(!isPrepare(file1, file2)){
            System.out.println("源文件有问题,未找到!");
            return;
        }
        try (
            BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file1));
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(file2));
        ){
            byte[] bytes = new byte[1024];
            int length;
            while ( (length = bufferedInputStream.read(bytes)) != -1){
                bufferedOutputStream.write(bytes,0,length);
            }
            bufferedOutputStream.flush();
        }
    }

    public static boolean isPrepare(File src, File dest){
        if (!src.exists())return false;
        if(!dest.exists()){
            try {
                dest.getParentFile().mkdir();
                dest.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    // 复制文件夹
    public static void copyFolder(String src, String dest) throws IOException {
        File file1 = new File(src);
        if(!file1.exists() || !file1.isDirectory()){
            System.out.println("文件夹未找到!");
            return ;
        }
        long start = System.currentTimeMillis();
        copyAllFolder(file1, dest);
        long end = System.currentTimeMillis();
        System.out.println("文件夹复制完成!");
        System.out.println("用时 = " + (end - start) + "ms\n");
    }

    public static void copyAllFolder(File src, String dest) throws IOException {
        File[] files = src.listFiles();
        for (File file: files){
            if(file.isFile()){
                copyFile(file.getCanonicalPath(),dest+"\\"+file.getName());
            }else if (file.isDirectory()){
                copyAllFolder(file,dest+"\\"+file.getName());
            }
        }
    }
}

2 查找文件内容

项目目录是 xxx,遍历该目录下所有的 java 文件(包括子文件夹)
找出文件内容包括 Magic 的那些文件,并打印出来

package14个程序_IO.综合练习.文件查找;

import java.io.*;

public class test {
    public static void main(String[] args) throws FileNotFoundException {
        long start = System.currentTimeMillis();
        String path = "src\\第14个程序_IO\\综合练习\\文件查找\\src";
        File file = new File(path);
        if(!file.exists()){
            System.out.println("该文件夹不存在!");
            return;
        }
        search(file,"File");
        long end = System.currentTimeMillis();
        System.out.println("用时: " + (end - start) + " ms");
    }

    public static void search(File folder, String mysearch) {
        File[] files = folder.listFiles();
        for (File file:files){
            if(file.isDirectory()){
                search(file, mysearch);
            }else if(file.isFile() && file.getName().endsWith(".java")){
                char[] datas = new char[(int) file.length()];
                try (
                    BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
                ){
                    bufferedReader.read(datas);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if(String.valueOf(datas).contains(mysearch)){
                    System.out.println("找到字符串在 " + file.getName() + " - " + file.getAbsolutePath());
                }
            }
        }
    }
}

xls 读取

https://blog.51cto.com/u_12329518/3863604

@Service
public class MongoUpdateImpl implements MongoUpdate {

    private static final Logger LOGGER = LoggerFactory.getLogger(MongoUpdateImpl.class);

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public void update() throws BiffException, IOException {

        List<String> listOld = new ArrayList<>();
        List<String> listNew = new ArrayList<>();
        readExcel(listOld, listNew);


        int size = listOld.size();
        for (int i = 0; i < size; i++) {
            Query query = new Query(Criteria.where("name").is(listOld.get(i)));
            Update update = new Update().set("name", listNew.get(i));
            mongoTemplate.updateMulti(query, update, "testdata");
        }

    }


    public void readExcel(List<String> listOld, List<String> listNew) throws BiffException, IOException {
        File file = new File("src/main/resources/data/data.xls");
        Workbook rwb = Workbook.getWorkbook(file);
        Sheet rs = rwb.getSheet(0);
        int colums = rs.getColumns();
        int rows = rs.getRows();

        LOGGER.info("colums = " + colums);
        LOGGER.info("rows = " + rows);

        for (int i = 1; i < rows; i++) {
            listOld.add(rs.getCell(1,i).getContents());
            listNew.add(rs.getCell(2,i).getContents());
        }
        
        
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_1403034144

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值