在学习过滤器之前,先来做一个案例。
题目:文件搜索,搜索 D:\java 目录中 .java 文件。
分析:
1. 目录搜索,无法判断多少级目录,使用递归,遍历所有目录
2. 遍历目录时,获取的子文件,通过文件名称,判断是否符合条件
实现:
1 public class FileDemo {
2 public static void main(String[] args) {
3 // 创建File对象
4 File dir = new File("D:\\java");
5 // 调用打印目录方法
6 printDir(dir);
7 }
8 public static void printDir(File dir) {
9 // 获取子文件和目录
10 File[] files = dir.listFiles();
11 // 循环打印
12 for (File file : files) {
13 if (file.isFile()) {
14 // 是文件,判断文件名并输出文件绝对路径
15 if (file.getName().toLowerCase().endsWith(".java")) {
16 System.out.println("文件名:" + file.getAbsolutePath());
17 }
18 } else {
19 // 是目录,继续遍历,形成递归
20 printDir(file);
21 }
22 }
23 }
24 }
文件过滤器
java.io.FileFilter 是一个接口,是 File 的过滤器。
在File类中有两个和ListFiles重载的方法,方法的参数传递的就是过滤器。
接口一:
File[] listFiles(FileFilter filter) java.io.FileFilter接口:用于抽象路径名(File对象)的过滤器。
作用:返回所有满足指定过滤器的文件和目录,如果给定的 filter 为 null,则接受所有路径名。否则,当且仅当在路径名上调用过滤器的 FileFilter.accept(java.io.File) 方法返回 true时,该路径名才满足过滤器。如果当前 File 对象不表示一个目录,或者发生 I/O 错误,则返回 null。
抽象方法:用来过滤文件的方法
boolean accept(File pathname) 测试指定抽象路径名是否应该包含在某个路径名列表中。
参数: File pathname:使用ListFiles方法遍历目录,得到的每一个文件对象
接口二:
File[] listFiles(FilenameFilter filter) java.io.FilenameFilter接口:实现此接口的类实例可用于过滤器文件名。
作用:返回所有满足指定过滤器的文件和目录。如果给定 filter 为 null,则接受所有路径名。否则,当且仅当在路径名上调用过滤器的 FilenameFilter.accept(java.io.File, java.lang.String) 方法返回 true 时,该路径名才满足过滤器。如果当前File对象不表示一个目录,或者发生 I/O 错误,则返回 null。
抽象方法:用来过滤文件的方法
boolean accept(File dir, String name) 测试指定文件是否应该包含在某一文件列表中。
参数:
File dir:构造方法中传递的被遍历的目录
String name:使用ListFiles方法遍历目录,获取的每一个文件/文件夹的名称
注意:两个过滤器接口是没有实现类的,需要自己写实现类,重写过滤的方法accept,在方法中自己定义过滤的规则
FileFilter 过滤器的原理:
Demo:
1 // 创建过滤器FileFilter的实现类,重写过滤方法accept,定义过滤规则
2 public class FileFilterImpl implements FileFilter{
3 @Override
4 public boolean accept(File pathname) {
5 /*
6 过滤的规则:
7 在accept方法中,判断File对象是否是以.java结尾
8 是就返回true
9 不是就返回false
10 */
11 //如果pathname是一个文件夹,返回true,继续遍历这个文件夹
12 if(pathname.isDirectory()){
13 return true;
14 }
15
16 return pathname.getName().toLowerCase().endsWith(".java");
17 }
18 }
测试类:
1 // 测试类
2 public static void main(String[] args) {
3 File file = new File("c:\\abc");
4 getAllFile(file);
5 }
6
7 /*
8 定义一个方法,参数传递File类型的目录
9 方法中对目录进行遍历
10 */
11 public static void getAllFile(File dir){
12 File[] files = dir.listFiles(new FileFilterImpl());//传递过滤器对象
13 for (File f : files) {
14 //对遍历得到的File对象f进行判断,判断是否是文件夹
15 if(f.isDirectory()){
16 //f是一个文件夹,则继续遍历这个文件夹
17 //我们发现getAllFile方法就是传递文件夹,遍历文件夹的方法
18 //所以直接调用getAllFile方法即可:递归(自己调用自己)
19 getAllFile(f);
20 }else{
21 //f是一个文件,直接打印即可
22 System.out.println(f);
23 }
24 }
25 }
Lambad 优化
1、使用匿名内部类
Demo:
1 public static void main(String[] args) {
2 File file = new File("c:\\abc");
3 getAllFile(file);
4 }
5
6 public static void getAllFile(File dir){
7 //传递过滤器对象 使用匿名内部类
8 File[] files = dir.listFiles(new FileFilter() {
9 @Override
10 public boolean accept(File pathname) {
11 //过滤规则,pathname是文件夹或者是.java结尾的文件返回true
12 return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".java");
13 }
14 });
15 File[] files = dir.listFiles(new FilenameFilter() {
16 @Override
17 public boolean accept(File dir, String name) {
18 //过滤规则,pathname是文件夹或者是.java结尾的文件返回true
19 return new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".java");
20 }
21 });
22 for (File f : files) {
23 //对遍历得到的File对象f进行判断,判断是否是文件夹
24 if(f.isDirectory()){
25 //f是一个文件夹,则继续遍历这个文件夹
26 //我们发现getAllFile方法就是传递文件夹,遍历文件夹的方法
27 //所以直接调用getAllFile方法即可:递归(自己调用自己)
28 getAllFile(f);
29 }else{
30 //f是一个文件,直接打印即可
31 System.out.println(f);
32 }
33 }
34 }
2、使用Lambda 表达式
FileFilter 是只有一个方法的接口,因此可以用lambda表达式简写
Demo:
1 public static void main(String[] args) {
2 File file = new File("c:\\abc");
3 getAllFile(file);
4 }
5 /*
6 定义一个方法,参数传递File类型的目录
7 方法中对目录进行遍历
8 */
9 public static void getAllFile(File dir){
10
11 // 方式一
12 File[] files = dir.listFiles((File pathname)->{
13 return pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".java");
14 });
15
16 // 方式一 Lambda 优化后
17 File[] files = dir.listFiles(pathname->pathname.isDirectory() || pathname.getName().toLowerCase().endsWith(".java"));
18
19 // 方式二
20 File[] files = dir.listFiles((File d, String name)->{
21 //过滤规则,pathname是文件夹或者是.java结尾的文件返回true
22 return new File(d,name).isDirectory() || name.toLowerCase().endsWith(".java");
23 });
24
25 // 方式二 Lambada 优化后
26 File[] files = dir.listFiles((d,name)->new File(d,name).isDirectory() || name.toLowerCase().endsWith(".java"));
27
28 // 遍历输入
29 for (File f : files) {
30 //对遍历得到的File对象f进行判断,判断是否是文件夹
31 if(f.isDirectory()){
32 //f是一个文件夹,则继续遍历这个文件夹
33 //我们发现getAllFile方法就是传递文件夹,遍历文件夹的方法
34 //所以直接调用getAllFile方法即可:递归(自己调用自己)
35 getAllFile(f);
36 }else{
37 //f是一个文件,直接打印即可
38 System.out.println(f);
39 }
40 }
41 }