Java 之 文件过滤器

  在学习过滤器之前,先来做一个案例。

  题目:文件搜索,搜索 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 }
原文地址:https://www.cnblogs.com/niujifei/p/11482469.html