1.流的概念

  • 概念

    • 内存与存储设备之间传输数据的通道。
    • 数据借助于流来进行传输

      2.流的分类

      按方向(重点)

      输入流:将<存储设备>中的内容读入到<内存>中

      输出流:将<内存>中的内容写入到<存储设备>中

    • image.png

      按单位

    • 字节流:以字节为单位,可以读写所有数据。

    • 字符流:以字符为单位,只能读写文本数据。

      按功能

    • 节点流:具有实际传输数据的读写功能

    • 过滤流:在节点流的基础之上增强功能

      3.字节流

  • 首先来看字节流的父类(抽象类)

    InputStream:字节输入流 表示字节输入流的所有类的超类

    • image.png

      OutputStream:字节输出流 次抽象类是表示输出字节流的所有类的超类,输出流接受输出字节并将这些字节发送到某个接收器。

    • image.png

image.png

4.文件字节流

FileInputStream

  • public int read(byte[] b)// 从流中读取多个字节,将读到的内容存放在b数组内,返回实际读到的数字,如果达到文件的地步,则返回-1 ```java /*
    • @Descripttion: FileInputStream相关学习
    • @version:
    • @Author: Addicated
    • @Date: 2020-11-07 20:18:06
    • @LastEditors: Addicated
    • @LastEditTime: 2020-11-07 20:47:53 */ package review.IO;

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

public class Demo1 { public static void main(String[] args) throws IOException { // 1,创建FileInputStream,并制定文件路径 FileInputStream fis = new FileInputStream(“src\main\java\review\IO\memo.txt”); // // 2,读取文件 // fis.read(); // 一个字节一个字节的进行读取的方式 // int data =0; // while((data=fis.read())!=-1){ // System.out.println(data); // }

  1. // 一次读多个字节 字节长度决定读多少个字节
  2. // byte[] buf = new byte[3];
  3. // // 返回值 为读取了的字节的个数
  4. // int count = fis.read(buf); // 读到的字节返回到buf这个字节类型的数组中
  5. // System.out.println(new String(buf));
  6. // System.out.println("读取了多少字节:" + count);
  7. // 优化,一次性读完所有数据
  8. byte[] buf = new byte[1024];
  9. int count = 0;
  10. // * @param b the buffer into which the data is read.
  11. // * @return the total number of bytes read into the buffer, or
  12. // * <code>-1</code> if there is no more data because the end of
  13. // * the file has been reached.
  14. // 观察原码得知,如果没有数据了,就返回-1,即,不返回-1,表示仍有数据,继续进行遍历
  15. while ((count = fis.read(buf)) != -1) {
  16. System.out.println(new String(buf, 0, count));
  17. }
  18. // 3,关闭
  19. fis.close();
  20. System.out.println("执行完毕");
  21. }

}

<a name="pdO9q"></a>
## FileOutputStream

   - public ovid write(byte[] e) 一次性多写几个字节,将B数组中所有音节,写入输入流
```java
/*
 * @Descripttion: 演示文件输出流
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-07 21:02:38
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-07 21:22:47
 */
package review.IO;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class Demo2 {
    public static void main(String[] args) throws IOException {
        // 1.创建文件字节输出流对象
        // 当前调用的构造方法每次都会覆盖写入
        FileOutputStream fos = new FileOutputStream("memo1.txt");
        // 追加写入 添加一个参数为true即可
        // FileOutputStream fos = new FileOutputStream("memo1.txt",true);

        // 写入文件 以字符写入
        // fos.write(97);
        // fos.write('c');
        // fos.write('b');

        String string = "helloAddicated";
        // string.getBytes 将字符串自动转码成字节类型数组并返回
        fos.write(string.getBytes());

        fos.close();
        System.out.println("执行结束");

    }
}

案例 文件字节流复制文件

/*
 * @Descripttion: 
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-07 21:29:33
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-07 21:37:40
 */
package review.IO;

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

public class Demo3 {
    public static void main(String[] args) throws IOException {
        // 1.创建流
        // 字节输入流读取
        FileInputStream fis = new FileInputStream("D:\\学生成绩证明.pdf");
        // 创建字节输出流输出
        FileOutputStream fos = new FileOutputStream("D:\\学生成绩证明copy.pdf");
        // 一边读,一边写入
        byte[] buf =new byte[1024*1024*1024];
        int count =0;
        while((fis.read(buf))!=-1){
            fos.write(buf,0,count);
        }
        fis.close();
        fos.close();
        System.out.println("文件复制完毕了~~~");
    }
}

5.字节缓冲流

缓冲流:BufferedInputStream/BufferedOutputStream

  • 提高IO效率,减少访问磁盘的次数
  • 数据存储在缓冲区,flush是将缓冲区的内容写入文件中,也可以直接close。

    BufferedInputStream

    ```java /*
    • @Descripttion: 使用字节缓冲流来读取文件
    • @version:
    • @Author: Addicated
    • @Date: 2020-11-07 22:59:59
    • @LastEditors: Addicated
    • @LastEditTime: 2020-11-08 08:52:00 */ package review.IO;

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

public class Demo4 { public static void main(String[] args) throws IOException { // 1.创建字节缓冲流 需要一个输入流对象象来作为参数传入 FileInputStream fis = new FileInputStream(“src\main\java\review\IO\memo.txt”); BufferedInputStream bis = new BufferedInputStream(fis); // 读取 // fis 是从硬盘读,bis是从缓存区读取 /**

     * The maximum size of array to allocate. Some VMs reserve some header words in
     * an array. Attempts to allocate larger arrays may result in OutOfMemoryError:
     * Requested array size exceeds VM limit
     */  
    // private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
    // 查看原码得知buffered读的大小默认为8k
    // int data = 0;
    // while ((data = bis.read()) != -1) {
    //     System.out.print((char) data);
    // }
    // 自己定义缓冲区的大小进行读取
    byte[] buf = new byte[1024];
    int count=0;
    while((count=bis.read(buf))!=-1){
            System.out.println(new String(buf,0,count));
    }
    // 关闭
    bis.close();
}

}

<a name="JKlle"></a>
### BufferedOutputStream

   - 该类实现缓冲的输出流,通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统。从jdk1.0开始
```java
/*
 * @Descripttion:  使用字节缓冲流写入文件
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-08 08:53:59
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-08 09:34:44
 */
package review.IO;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;

public class Demo5 {
    public static void main(String[] args) throws Exception {
        // 1,创建字节输出缓冲流
        FileOutputStream fos = new FileOutputStream("memo2.text");
        BufferedOutputStream bos = new BufferedOutputStream(fos);

        // 2,写入文件
        for (int i = 0; i < 10; i++) {
            bos.write("hello addicated\r\n".getBytes()); // 先写入到8k的缓冲区
            bos.flush(); // 刷新到硬盘中
        }

        // 关闭(内部会自动调用flush方法,)即
        bos.close();
    }
}

6.对象流

对象流 : ObjectOutputStream / ObjectInputStream

  • 增强了缓冲区功能
  • 增强了读写8中基本数据类型和字符串功能
  • 增强了读写对象的功能
    • readObject() 从流中读一个对象
    • writeObject(Object obj) 向流中写入一个对象
  • 使用流传输对象的过程称为序列化,反序列化

    注意点

  • 在运用的时候必须要让实体类实现serializable接口

  • 序列化类中的对象属性也要求实现serializable接口
  • 序列化版本号ID,保证序列化的类和反序列化的类是同一个类
  • 使用transient修饰属性,这个属性就不能序列化了,transient意为瞬间的
  • 静态属性也是不能序列化的
  • 序列化多个对象,可以借助集合的形式吧对杨压入集合中然后通过对集合进行序列化反序列化操作实现多对象序列化
// 对象流操作的pojo类
public class Student  implements Serializable{
    // 用来保证序列化和反序列化操作的是同一个类
    private static final long serialVersionUID=100L;

    private String name;
    // transient 修饰的属性不会被序列化,
    private transient int age;
    public String getName() {
        return name;
    }

ObjectOutputSteam

/*
 * @Descripttion: 对象流系列--序列化(写入操作
 * 要求,必须让实体类实现seriable 接口
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-08 09:45:59
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-08 11:05:52
 */
package review.ObjIO;

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

public class demo1 {
    public static void main(String[] args) throws IOException {
        // 1.创建对象流
        FileOutputStream fos = new FileOutputStream("stu.bin"); // bin表示为一个二进制文件
        // 对象流的输出同时需要给与一个底层的流对象作为参数
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        // 2 序列化写入操作
        // 创建pojo对象,
        Student stu = new Student("adi", 13);
        oos.writeObject(stu);

        // 3 关闭
        oos.close();
        // Exception in thread "main" java.io.NotSerializableException:
        // review.ObjIO.Student
        // 对象不可写入的异常。对象如果想要序列化,需要实现一个Serializable接口
        // serializable 接口仅是一个表示,该接口中没有任何需要实现的接口方法声明
    }
}

ObjectInputStream

/*
 * @Descripttion:  使用objectinputstream实现反序列化(读取重构成对象
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-08 12:01:00
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-08 12:31:50
 */
package review.ObjIO;

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

public class demo2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 1,创建独享流
        FileInputStream fis = new FileInputStream("stu.bin");
        ObjectInputStream ois = new ObjectInputStream(fis);

        // 2.读取文件 反序列化文件  不可多次读取同一个对象文件,会抛出eof异常
        Student s = (Student)ois.readObject();
        // 3 关闭
        ois.close();
        System.out.println("执行完毕");
        System.out.println(s.toString());
    }
}

7.编码方式

字符编码

  • ISO-8859-1 收录除ASCII外,还包括西欧,希腊语,泰语,阿拉伯语,希伯来语对应的文字符号
  • UTF-8 针对Unicode码表的可变长度字符编码
  • GB2312 简体中文
  • GBK 健体中文,扩充
  • BIG 台湾,繁体中文
  • 当编码反射和解码凡是不一致时,会出现乱码

    8.字符流

    字符流的父类(抽象类):

    Reader 字符输入流

    • public int read()
    • public int read(char[] c )
    • public int read(char[] b,int off,int len)

      Writer 字符输出流

    • public void write(int n) {}

    • public void write(String str)
    • public void write(char[] c)

      8.1 文件字符流

      FileReader

  • public int read(char[] c) // 从流中读取多个字符,将读到的内容存入c数组,返回实际读到的字符数,如果达到文件的尾部。返回-1 ```java /*

    • @Descripttion:
    • @version:
    • @Author: Addicated
    • @Date: 2020-11-08 13:34:09
    • @LastEditors: Addicated
    • @LastEditTime: 2020-11-08 15:15:28 */ package review.ObjIO;

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

public class demo3 { public static void main(String[] args) throws IOException { // 1.创建FileReader 文件字符输入流 FileReader fr = new FileReader(“stu.bin”); // 2.读取

    // 2.1 单个字符读取
    // int data =0;
    // while((data=fr.read())!=-1){
    // System.out.print((char)data);
    // }

    char[] buf = new char[1024];
    int count = 0;
    while ((count = fr.read(buf)) != -1) {
        System.out.println(new String(buf, 0, count));
    }

    // 3.关闭
    fr.close();
}

} /*

  • @Descripttion:
  • @version:
  • @Author: Addicated
  • @Date: 2020-11-08 13:34:09
  • @LastEditors: Addicated
  • @LastEditTime: 2020-11-08 15:15:28 */ package review.ObjIO;

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

public class demo3 { public static void main(String[] args) throws IOException { // 1.创建FileReader 文件字符输入流 FileReader fr = new FileReader(“stu.bin”); // 2.读取

    // 2.1 单个字符读取
    // int data =0;
    // while((data=fr.read())!=-1){
    // System.out.print((char)data);
    // }

    char[] buf = new char[1024];
    int count = 0;
    while ((count = fr.read(buf)) != -1) {
        System.out.println(new String(buf, 0, count));
    }

    // 3.关闭
    fr.close();
}

}

<a name="GjJcg"></a>
## FileWriter

   - public void write(String str)// 一次写多个字符,将b数组中所有字符,写入输入流
```java
/*
 * @Descripttion: 使用fileWriteer来写入文件, 
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-08 15:18:12
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-08 16:16:33
 */
package review.ObjIO;

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

public class demo4 {
    public static void main(String[] args) throws IOException {
        // 1.创建一个filewriter对象
        FileWriter fw =new FileWriter("fwOutPut.text");

        // 2.写入
        for (int i = 0; i < 10; i++) {
            fw.write("hello this is addicated\r\n");
            fw.write("java no 1 ");
            fw.flush();
        }
        // 3关闭
        fw.close();

    }
}

运用实例,,使用文件字符流来copy文件

  • 注意点。使用fileReader 和 FileWriter 复制文本文件,不能复制图片或者二进制文件,因为二进制文件没有字符编码,无法被识别 ```java /*
    • @Descripttion:
    • @version:
    • @Author: Addicated
    • @Date: 2020-11-08 16:19:00
    • @LastEditors: Addicated
    • @LastEditTime: 2020-11-08 16:33:17 */ package review.ObjIO;

import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.FileWriter;

public class demo5_homework { public static void main(String[] args) throws Exception {

    // 1.字符读取流这样的操作无法读除了文本意外的文件,应当使用字节流进行读取
    FileReader fReader = new FileReader("memo2.text");
    FileWriter fWriter = new FileWriter("homework.txt");
    // 进行读写
    int data =0;
    while((data=fReader.read())!=-1){
        fWriter.write(data);
    }
    // 关闭流
    fReader.close();
    fWriter.close();

}

}

<a name="dzsoE"></a>
# 9.字符缓冲流
<a name="eC2S3"></a>
## 缓冲流,BufferedReader / BufferedWriter

   - 高效读写
   - 支持输入换行符
   - 可以一次写一行,读一行
<a name="6X7Oy"></a>
## BufferedReader
```java
/*
 * @Descripttion: 
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-08 16:49:01
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-08 16:59:43
 */
package review.ObjIO;

import java.io.BufferedReader;
import java.io.FileReader;

public class demo6 {
    public static void main(String[] args) throws Exception {
        // 字符缓冲流的学习 通过字符缓冲流读取文件
        FileReader fReader = new FileReader("memo1.txt");
        // 缓冲流需要一个输入流对象作为参数
        BufferedReader bufferedReader = new BufferedReader(fReader);
        // 2 读取
        // 第一种方式读取
        // char[] buf = new char[1024]; // 设定读取到缓冲区的数据大小
        // int count =0; //
        // while((count=bufferedReader.read(buf))!=-1){
        //     System.out.println(count); // count为实际读取的字符个数
        //     System.out.println(new String(buf,0,count));
        // }

        // 第二种方式进行读取  一行一行的堵
       String line =  null;
            while((line = bufferedReader.readLine())!=null){
                // 如果line不为空,则代表仍有数据,可以继续向下进行遍历 
                System.out.println(line);
            }

        // 关闭
        bufferedReader.close();
    }
}

BufferedWriter

/*
 * @Descripttion: 
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-08 17:01:22
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-08 20:09:28
 */
package review.ObjIO;

import java.io.BufferedWriter;
import java.io.FileWriter;

public class demo7 {
    public static void main(String[] args) throws Exception {
        // bufferedWriter 的学习和使用
        // 1,创建bufferedWriter
        FileWriter fw = new FileWriter("BUFOUT.txt");
        BufferedWriter bw =new BufferedWriter(fw);

        // 2.写入数据
        for (int i = 0; i < 10; i++) {
            bw.write("addicated studying bufferedWriter");
            bw.newLine(); // 写入一个换行符 根据操作系统决定的换行符
            bw.flush();
        }
        // 3,关闭流
        bw.close();
    }
}

10.打印流

PrintWriter

  • 封装了print() / println() 方法,支持写入后换行
  • 支持数据原样打印 ```java /*
    • @Descripttion: 学习printWriter
    • @version:
    • @Author: Addicated
    • @Date: 2020-11-08 22:33:03
    • @LastEditors: Addicated
    • @LastEditTime: 2020-11-08 22:57:58 */ package review.ObjIO;

import java.io.FileNotFoundException; import java.io.PrintWriter;

public class demo8 { public static void main(String[] args) throws FileNotFoundException { // 1 创建打印流 PrintWriter pw = new PrintWriter(“print.txt”);

    // 2 打印
    pw.println("this is a printWriter test~");
    pw.println(3.14);
    pw.println(true);

    // 3 流关闭
    pw.close();
}

}

<a name="VH60X"></a>
# 11.转换流
<a name="MHMjG"></a>
##  桥转换流:InputStreamReader / OutputStreamWriter
可以将字节流转换为字符流。<br />可以设置字符的编码方式。<br />实际上是 内存中的字符,和硬盘中的字节之间的转换
<a name="PR2xH"></a>
### InputStreamReader
```java
/*
 * @Descripttion:   InputStreamReader 读取文件
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-09 14:27:10
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-09 15:04:46
 */
package review.StreamIO;

import java.io.FileInputStream;
import java.io.InputStreamReader;

public class demo1 {
    public static void main(String[] args) throws Exception {
        // 1 创建 inputStreamReader 对象
        FileInputStream fis = new FileInputStream("memo1.txt");
        // 参数为一个文件输入流对象,还有字符编码
        // InputStreamReader inputStreamReader = new InputStreamReader(fis, "utf-8");
        // 如果字符编码与目标文件不一致,会输出乱码,所以在读写的时候必须保持编码一致
        InputStreamReader inputStreamReader = new InputStreamReader(fis, "gbk");

        // 2 读取文件
        int data = 0;
        while ((data = inputStreamReader.read()) != -1) {
            System.out.print((char) data);
        }

        // 3.关闭流
        inputStreamReader.close();
    }
}

OutputStreamWriter

/*
 * @Descripttion: 使用outPutStreamWriter 写入文件,使用指定的编码
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-09 15:05:04
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-09 15:18:25
 */
package review.StreamIO;

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

public class demo2 {
    public static void main(String[] args) throws Exception {
        // 创建 outPutStreamWriter
        FileOutputStream fOutputStream = new FileOutputStream("outputStream.txt");
        // 作为参数需要字节输出流
        OutputStreamWriter osw = new OutputStreamWriter(fOutputStream, "utf-8");

        // 2进行写入
        for (int i = 0; i < 10; i++) {
            osw.write("我爱徐卓轶\r\n");
            osw.flush();

        }
        // 3 关闭流
        osw.close();

    }
}

12.File类

  • 概念:代表物理盼复中的一个文件或者盼复中的一个文件或者文件夹

文件操作
image.png

/*
 * @Descripttion: 演示file类的使用
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-09 15:46:17
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-09 16:58:00
 */
package review.StreamIO;

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

public class FileC {
    public static void main(String[] args) throws IOException {
        // 分隔符
        // 文件操作
        // 文件夹操作
        separator();
        fileOpe();
        dirOper();
    }

    // 分隔符
    public static void separator() {
        System.out.println("路径分隔符" + File.pathSeparator);
        System.out.println("名称分隔符" + File.separator);
    }

    // 文件操作
    public static void fileOpe() throws IOException {
        // 1.创建文件
        // 创建文件对象,然后使用对象的createNewFile方法
        File file = new File("newFile.txt");
        System.out.println(file.toString());

        // 判断文件是否存在 真 为存在,假 为不存在
        if (!(file.exists())) {
            boolean b = file.createNewFile();
            System.out.println("创建结果:" + b);

        }
        // 2 删除文件
        // 直接删除
        System.out.println("删除结果:" + file.delete());
        // 使用jvm退出时进行删除
        // file.deleteOnExit();
        // Thread.sleep(5000);

        // 3 获取文件信息
        System.out.println("获取文件的绝对路径:" + file.getAbsolutePath());
        System.out.println("获取路径:" + file.getPath());
        System.out.println("获取名称:" + file.getName());
        System.out.println("获取父目录:" + file.getParent());
        System.out.println("获得文件长度:" + file.length());
        System.out.println("获得文件的创建时间:" + new Date(file.lastModified()).toLocaleString());

        // 4 判断
        System.out.println("是否可写" + file.canWrite());
        System.out.println("是否可读" + file.canRead());
        System.out.println("是否可执行" + file.canExecute());
        System.out.println("是否是文件" + file.isFile());
        System.out.println("是否隐藏" + file.isHidden());

    }

    // 文件夹操作
    public static void dirOper() {
        // 1.创建文件夹
        File dir = new File("D:\\addicated\\test");
        if (!(dir.exists())) {
            System.out.println(dir.mkdirs());// 返回为布尔型
            // dir.mkdirs();// 创建多级目录
            // dir.mkdir(); // 创建单级目录
        }
        // 2 删除文件夹
        // 直接删除 ,,使用jvm删除
        dir.delete(); // 直接删除,只能删除空目录,且是最后一个目录
        // jvm进行删除
        dir.deleteOnExit();

        // 3 获取文件夹信息
        System.out.println("获取绝对路径:" + dir.getAbsolutePath());
        System.out.println("获取路径:" + dir.getPath());
        System.out.println("获取文件夹名称:" + dir.getName());
        System.out.println("获取父级目录:" + dir.getParent());
        System.out.println("获得文件的创建时间:" + new Date(dir.lastModified()).toLocaleString());

        // 4 判断
        System.out.println("是否是文件夹:" + dir.isDirectory());
        System.out.println("是否是隐藏的" + dir.isHidden());

        // 5 遍历文件夹
        File dir2 = new File("D:\\");
        String[] files = dir2.list();
        File[] f1 = dir2.listFiles(); // listFiles 返回的是file类型的数组
        for (String string : files) {
            System.out.println(string);
        }
    }

}

13.FileFilter接口

  • public interface FileFilter
    • boolean accept(File pathname)
  • 当调用File类中的listFiles()方法时,支持传入FileFilter接口接口实现类,对获取文件进行过滤,只有满足条件的文件的才可出现在listFiles()的返回值中

          // 通过lamda表达式的方式重写accept方法 即 进行过滤的规则,然后达到规则
          System.out.println("---------演示 fileFileter接口的使用");
         File[] f2= dir2.listFiles(new FileFilter(){
              @Override
              public boolean accept(File pathname) {
                  if(pathname.getName().endsWith(".pdf")){
                      return true;
                  }
                  return false;
              }
          });
          for (File file : f2) {
              System.out.println(file.getName());
          }
      }
    

    14.递归遍历和递归删除

  • 案例,递归遍历文件夹,包括子文件夹
    ```java /*

    • @Descripttion:
    • @version:
    • @Author: Addicated
    • @Date: 2020-11-09 18:13:20
    • @LastEditors: Addicated
    • @LastEditTime: 2020-11-09 18:18:25 */ package review.StreamIO;

import java.io.File;

public class case1 { public static void main(String[] args) { listDir(new File(“D:\“));

    // 递归遍历文件夹
}

public static void listDir(File dir) {
    File[] files = dir.listFiles(); // 返回为file类型的数组,
    System.out.println(dir.getAbsolutePath());
    if (files != null && files.length > 0) { // 对其意义判断,只要是目录,就进行
        for (File file : files) {
            if (file.isDirectory()) {
                listDir(file);// 这个地方用到了递归 ,
            } else {
                System.out.println(file.getAbsolutePath());
            }
        }
    }
}

// 递归删除文件夹
public static void deleteDir(File dir) {
    File[] files = dir.listFiles();
    // 首先判断files对象不为空,长度大于0
    if (files != null && files.length > 0) {
        for (File file : files) {
            if(file.isDirectory()){
                deleteDir(file); // 如果是目录,就递归删除
            }else{
                // 删除文件 
                System.out.println(file.getAbsolutePath()+"删除" + file.delete());
            }
        }
    }
    System.out.println(dir.getAbsolutePath()+"删除" + dir.delete());
}

}

<a name="DScyN"></a>
# 15. 补充 Properties

- properties 属性集合  继承hashtable 线程安全
- 特点
   - 存储属性名和属性值
   - 属性名和属性值都是字符串类型
   - 没有泛型
   - 和流有关
```java
/*
 * @Descripttion: 
 * @version: 
 * @Author: Addicated
 * @Date: 2020-11-09 18:34:46
 * @LastEditors: Addicated
 * @LastEditTime: 2020-11-09 18:45:28
 */
package review.StreamIO;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import java.util.Set;

public class properties {
    public static void main(String[] args) throws IOException {
        // 1 创建集合
        Properties properties = new Properties();

        // 2 添加数据
        properties.setProperty("username", "addicated");
        properties.setProperty("age", "26");
        System.out.println(properties.toString());
        // 3 遍历方式
        // keyset 取key的set集合
        // entrySet 取 键值对的集合
        // stringPropertyNames() 返回所有属性名集合
        Set<String> names = properties.stringPropertyNames();
        for (String string : names) {
            System.out.println(string);
            // 取值的话可以根据键来进行对应值的取
            System.out.println(properties.getProperty(string));
        }

        // 4 和流有关的方法
        // =======list方法
        // PrintWriter pw = new PrintWriter("print.txt");
        // properties.list(pw);
        // pw.close();  // 将properties集合中的属性写入到本地的文件中

        /// -------store 方法
        // FileOutputStream fos = new FileOutputStream("print.properties");
        // properties.store(fos, "first commit ");
        // fos.close();

        // --------load 方法
        Properties p1= new Properties();
        FileInputStream fis =new FileInputStream("print.properties");
        p1.load(fis);
        fis.close();
        System.out.println(p1.stringPropertyNames());
    }
}

总结

流的概念

内存与存储设备之间传输数据的通道。

流的分类

输入流,输出流;字节流,字符流;节点流,过滤流

序列化,反序列化

讲对象通过流写入文件,成为序列化
吧对象从流中读到内存,叫反序列化

File对象

代表物理盼复中的一个文件或者文件夹
IO框架图解
JAVA Review系列--Day08 IO框架 - 图6