暑期自学 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() 方法
- listFiles () 遍历了 dir 目录下的每一个文件夹和文件,并将它们封装成 File 类对象。
- listFiles () 调用了 FileFilter () 中的 accept () 方法
- listFIles () 将封装好的 File 类对象数组传递给 accept 方法的参数 filename。
- listFiles () 做了哪三件事?看以下代码:
- 由于两个过滤器借口均只有一个抽象方法,我们可以在给
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 个字节的数据从数组输出到输出流
- 使用步骤
- 创建一个 FileOutputStream 对象,构造方法中写入数据到目的地
- 调用 FileOutputStream 对象中的 write 方法,把数据写入到文件中
- 释放资源
- 注意:三个步骤均需要处理 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)
从输入流中读取一定数量的字节
- 使用步骤
- 创建一个 FileInputStream 对象,构造方法中传递数据读取的目的地
- 调用 FileInputStream 对象中的 read 方法,将指定文件中的字节读出
- 释放资源
- 连续读取文件中字节时会使用到循环,代码示例如下
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 协议》,转载必须注明作者和本文链接
推荐文章: