暑期自学 Day 02 | File 类 和 IO 流(二)

递归

这一节开头提到了递归,应该是后面有用,先复习一下。

  • 两种:直接递归(自己调用自己),间接递归(A调用B,B调用C…)。
  • 要有终止条件,否则无限调用导致栈内存溢出
  • 构造方法不可递归

*在遍历文件时使用到了:只要是文件夹,就递归调用自定义遍历方法遍历下级文件夹

FileFilter 过滤器的原理和使用

FileFilter
  • 接口,用于抽象路径名(File 对象)的过滤器。
  • 内含抽象方法
    • boolean accept(File pathname) 测试指定抽象路径是否包含在某个路径列表中
      • File pathName - 使用listFiles()方法遍历目录得到的File类对象
      • 如果返回 true,则继续遍历;如果返回 false,则停止遍历该 File 类对象
FilenameFilter
  • 接口,用于过滤文件名称

  • 内含抽象方法

    • boolean accept(File dir, String name) 测试指定文件是否包含在某一文件列表,注意:第一个参数类型是 File 类型,第二个参数是 String 类型。
  • 两个接口的抽象方法都需要自己写实现类,重写过滤方法 accept(),自定义过滤规则。

  • 两个接口的区别:???

过滤器原理
  • 需求: 过滤指定类型的文件,如以.java结尾的文件
  • 明确
    • accept() 方法由谁调用?- listFiles()
    • accept() 方法参数 pathname 是什么?- 由 listFiles() 遍历得到的所有 File 类文件/文件名对象
      • listFiles() 做了哪三件事?看以下代码:
          File dir = new File("D:\\TAMU");
          File[] files = dir.listFiles(new FileFilter()); // 传递过滤器对象给 listFiles() 方法
        1. listFiles() 遍历了 dir 目录下的每一个文件夹和文件,并将它们封装成 File 类对象。
        2. listFiles() 调用了 FileFilter() 中的 accept() 方法
        3. listFIles() 将封装好的 File 类对象数组传递给 accept 方法的参数 filename。
    • 由于两个过滤器借口均只有一个抽象方法,我们可以在给 listFiles() 传参时使用 Lamda 表达式实现接口,而不用额外写一个实现类。

IO流 (输入输出流)

  • 流:数据(字符,字节)。1 字符 = 2字节;1字节 = 8 二进制位。
  • 字节流:InputStream, OutputStream;字符流:Reader, Writer
  • 为什么要在使用完 IO 流后释放资源?由于 Java 的垃圾回收机制无法对系统资源进行释放,所以需要手动释放,避免资源浪费。
字节输出流(OutputStream)
  • OutputStream 是抽象类,把内存中的数据写入磁盘的文件中
  • 数据写入原理:java 程序 -> JVM -> OS -> OS 调用写数据的方法 -> 把数据写入文件
    • 一些共性成员方法
      • public void close() 关闭输出流并释放相关资源
      • public void flush() 刷新输出流并写出缓冲的输出字节
      • public void write(byte[] b) 将b.length字节从字节数组写入输出流
      • public void write(byte[] b, int off, int len) 将从b[off]开始,len个字节的数据从数组输出到输出流
    • 使用步骤
      1. 创建一个 FileOutputStream 对象,构造方法中写入数据到目的地
      2. 调用 FileOutputStream 对象中的 write 方法,把数据写入到文件中
      3. 释放资源
        • 注意:三个步骤均需要处理 IOException; 在实际操作中构造 FileOutputStream 对象时,只有传入绝对文件路径才能写入成功,传入相对路径只能创建空文件。不知道这是为什么?
    • 往文件后追加写数据
      • FileOutputStream(String name, boolean append)FileOutputStream(File file, boolean append) append 为 true 时,可以在原文件中续写。
    • 写入换行
      • fos.write("\r\n".getBytes())
字节输入流 (InputStream)
  • InputStream 是抽象类,把磁盘文件的数据读取到内存中
  • java 程序 -> JVM -> OS -> OS 调用读取数据的方法 -> 把数据读取出
    • 一些共性成员方法
      • public void close() 关闭输入流并释放相关资源
      • public int read() 从输入流中读取下一个字节
      • public int read(byte[] b) 从输入流中读取一定数量的字节
    • 使用步骤
      1. 创建一个 FileInputStream 对象,构造方法中传递数据读取的目的地
      2. 调用 FileInputStream 对象中的 read 方法,将指定文件中的字节读出
      3. 释放资源
    • 连续读取文件中字节时会使用到循环,代码示例如下
      FileInputStream fis = new FileInputStream("d:\\test\\a.txt");
      int len = 0; // 用于获取返回字节的整型变量
      while ((len = fis.read()) != -1) { // 读取返回值为 -1 时说明文件数据全部读完
        System.out.println((char)len);
      }
      fis.close(); // **释放资源很重要**
    • 一次读取多个字节的方法
      int read(byte[] b) 从输入流中读取一定数量的字节,并存储在缓冲区数组 b 中(一般定义为 1024 的倍数)
      • 也还是明确两件事情:
        • byte[] 数组的作用?byte数组,有缓冲作用。每读取多个字节覆盖相应数组空间,如果最后剩余字节数 n 少于数组长度,只覆盖前 n 个数组空间
        • 返回值 int 是什么?是所读取字节的数量。如果读完返回 -1
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!