• [java进阶]——IO流,递归实现多级文件拷贝


    🌈键盘敲烂,年薪30万

    目录

    一、认识IO流

    二、了解编码与解码

    二、IO流体系

    三、基本字节输入输出流

    四、基本字符输入输出流

    4.1输入流

    4.2输出流

     4.3字符流自带的加载缓冲区功能(很重要!!!)

    五、多级文件拷贝

    六、高级输入输出流-缓冲流

    七、总结


    一、认识IO流

    IO流也叫输入流(intput)、输出流(onput),该流就像java程序同硬盘之间的一条数据传输通道,我们说的输入流、输出流是向java程序输入数据、从java程序输出数据

    二、了解编码与解码

    我们知道存储在文件里面的都是二进制0 1,数据在往文件里存储前会先转为二进制,转化为了二进制再经过编码存储到文件里面。

    假如我要存字符a,是如何编码的,a对应的ASCII码值为97,二进制为110 0001,补全8位比特位变为0110 0001,这就是a要存储的二进制,这也是英文字符的编码方案,那要是存储一个汉字呢,汉字也有对应的二进制的值,只不过这个表不是ASCII码表,而是GBK或者Unicode表,里面大约存储了2万多个汉字,2万多个汉字,我们用2个字节保存它的二进制戳戳有余,不同的标准有不同的编码方案,例如UTF-8编码方案一个汉字占3个字节,ANSI编码方案一个汉字占2个字节,我们要了解UTF-8编码方案。

    UTF-8英文字符编码过程

    UTF-8汉字编码过程

    解析:

    问题一有四个英文字符

    问题二两个英文字符2个汉字字符

    总结:

    Unicode字符集利用UTF-8的编码方案

    英文字符占一个字节且二进制第一位是0

    中文字符占3个字节且每个字节二进制第一位是1

    那你能不能解释一下为什么乱码呢???

    原因一:编码与解码规则不一样

    原因二:未读取完整个汉字字符

    二、IO流体系

    三、基本字节输入输出流

    3.1输入流

    适用范围: 可读取任何文件,一次性读取一个字节

    使用的三个步骤: 1.关联文件(建立流) 2.读数据 3.关闭流

    代码解析:

    构造方法里面可以是字符串,也可以是文件对象

    read()方法有两个功能,读取一个字节并返回它ascii码值的十进制,移动指针

    当读到文件末尾返回-1

    最后close关闭流,不关闭该文件会被一直占用

    1. FileInputStream fis = new FileInputStream("10_16\\a.txt");
    2. int tmp = 0;
    3. while((tmp = fis.read()) != -1){
    4. System.out.print((char)tmp);
    5. }
    6. fis.close();

    这样一个一个字节读取是不是太慢了啊,我们可以一次读取一个字节数组,这不就O了嘛

    代码解析:

    bytes用于保存每一次读取的数据,

    read也是读取字节,移动指针,并且返回读取字节的个数。

    注意:

    每一次读取新数据到数组会将原数据覆盖,所以如果最后一次没读够10字节,数组后面的内容是上一次读取的。

    read()括号里面要传入数组

    bytes数组里的数据是字符,不是它ASCII码的十进制了

    1. FileInputStream fis = new FileInputStream("10_16\\a.txt");//路径要两个\\
    2. byte[] bytes = new byte[10]; //一次性读取10个字节
    3. int len= 0;
    4. while((len= fis.read(bytes)) != -1){
    5. String s = new String(bytes, 0, len);
    6. System.out.print(s);
    7. }
    8. fis.close();

    3.2输出流

    代码解析:

    构造函数的第二个参数表示你要不要续写该文件,如果是false,会清空源文件内容

    不写默认为false

    \r,\n代表回车换行符,如果只写一个,编译器会帮我们补全

    write写入,最后别忘了关闭流

    1. FileOutputStream fos = new FileOutputStream("10_16\\a.txt",false);
    2. fos.write(97); //写入字符a
    3. fos.write('a');
    4. fos.write('\r'); //写入回车换行符
    5. byte[] bytes = {97, 98, 99};
    6. fos.write(bytes);//写入字符a b c
    7. fos.close();

    四、基本字符输入输出流

    4.1输入流

    注意事项

    只适用于读取纯文本文件(用记事本打开不会乱码),一次性读取一个字符

    上面我们说了不同的编码方案汉字占不同的字节,所以你用字节流一次性读取一个字节只是汉字的一部分,强转就会出现乱码,所以才用字符流。

    使用步骤

    1.关联文件路径 2.read() 3.关闭流

    代码分析:

    跟上面一样,也可以一次性读取多个字符数据,只不过要注意,数组要用char类型

    1. //一次读取一个有效字符
    2. FileReader fr = new FileReader("10_16\\a.txt");
    3. int tmp = 0;
    4. while ((tmp = fr.read()) != -1){
    5. System.out.print((char)tmp);
    6. }
    7. fr.close();
    8. //一次读取多个有效字符
    9. FileReader fr = new FileReader("10_16\\a.txt");
    10. int len = 0;
    11. char[] chars = new char[10];
    12. while ((len = fr.read(chars)) != -1){
    13. System.out.print(new String(chars, 0, len));
    14. }
    15. fr.close();
    4.2输出流

    可传入类型

    1. FileWriter fw = new FileWriter("10_16\\a.txt");
    2. fw.write("hello world");
    3. fw.close();
     4.3字符流自带的加载缓冲区功能(很重要!!!)

    利用字符流操作数据时,会在内存中开辟8192字节的缓冲区,每次读取或者写入数据都是先找缓冲区。

    五、多级文件拷贝

    核心思路:

    创建两个文件路径src与dest,一个为要拷贝的文件,一个为拷贝的目的地

    先创建改路径下的dest文件夹

    遍历src文件,如果不是文件,继续递归,如果是文件,拷贝

    1. private static void copyFile1(File src, File dest) throws IOException {
    2. //先创建文件夹
    3. dest.mkdir();
    4. //进入路径 遍历文件
    5. for (File file : src.listFiles()) {
    6. if(file.isDirectory()){
    7. //递归
    8. //这里的dest路径要好好想一下
    9. copyFile1(file, new File(src, file.getName()));
    10. }else{
    11. //拷贝文件
    12. FileInputStream fis = new FileInputStream(src);
    13. FileOutputStream fos = new FileOutputStream(dest);
    14. int tmp = 0;
    15. while ((tmp = fis.read()) != -1){
    16. fos.write(tmp);
    17. }
    18. //关闭流
    19. fos.close();
    20. fis.close();
    21. }
    22. }

    六、高级输入输出流-缓冲流

     缓冲流是基本字符流下的高级流,使用时要关联基本字符流

    俩个非常重要的方法 1.readline() 一次读取一行字符 2.newline() 添加换行符

    readline使用细节

    遇到回车算作一行,并且不会读取这个回车符

    返回类型是String,读到文件末尾返回null

    不要忘记关流欧~~

    1. File newfile = new File("IOTest1\\a.txt");
    2. BufferedReader br = new BufferedReader(new FileReader(newfile));
    3. String s = null;
    4. while((s = br.readLine()) != null){
    5. System.out.print(s);
    6. }
    7. br.close();

    writeline使用细节

    没什么细节,会使用就行了,要知道在不同操作系统下的回车换行符是不同的,所以你不用'\n' '\r'代替,只能用writeline()写入回车换行符

    记得关流~~

    1. BufferedWriter bw = new BufferedWriter(new FileWriter(newfile));
    2. bw.write("我真的快吐了~~");
    3. bw.newLine();
    4. bw.write("不喜欢IO流");
    5. bw.close();

    七、总结

    什么是输入流输出流???

    UTF-8编码方案是如何编码与解码的???

    操作纯文本文件可以用字符和字节流,不是纯文本文件用字节流

    读取有汉字的文件要用字符流去读

    字符流有缓冲区的概念

  • 相关阅读:
    go实现N个协程交替顺序打印自然数的详细解释
    MySQL学习笔记18
    人工智能领域的基础知识点汇总
    CSS网页标题图案和LOGO SEO优化
    72编辑距离
    哈希表专项练习 LeetCode
    成都Java开发已经饱和了?
    Retrofit
    Spring入门系列:浅析知识点
    Java—List
  • 原文地址:https://blog.csdn.net/Panci_/article/details/133917581