一、文件搜索

  • 需求 :

    遍历D:\aaa文件夹,及 aaa 文件夹的子文件夹并且只要.java结尾的文件

  • 分析

    1. 目录搜索,无法判断多少级目录,所以使用递归,遍历所有目录。
    2. 遍历目录时,获取的子文件,通过文件名称,判断是否符合条件。

代码实现

public class Demo05Recurison {
   
    public static void main(String[] args) {
   
        File file = new File("D:\\aaa");
        getAllFile(file);
    }

    /* 定义一个方法,参数传递File类型的目录 方法中对目录进行遍历 */
    public static void getAllFile(File dir){
   
        //System.out.println(dir);//打印被遍历的目录名称
        File[] files = dir.listFiles();
        for (File f : files) {
   
            //对遍历得到的File对象f进行判断,判断是否是文件夹
            if(f.isDirectory()){
   
                //f是一个文件夹,则继续遍历这个文件夹
                //我们发现getAllFile方法就是传递文件夹,遍历文件夹的方法
                //所以直接调用getAllFile方法即可:递归(自己调用自己)
                getAllFile(f);
            }else{
   
                //f是一个文件,直接打印即可
                /* D:\\aaa\\a.java 只要.java结尾的文件 1.把File对象f,转为字符串对象 */
                //String name = f.getName();//a.java
                //String path = f.getPath();//D:\\aaa\\a.java
                //String s = f.toString();//D:\\aaa\\aaa.java

                //把字符串,转换为小写
                //s = s.toLowerCase();

                //2.调用String类中的方法endsWith判断字符串是否是以.java结尾
                //boolean b = s.endsWith(".java");

                //3.如果是以.java结尾的文件,则输出
                /*if(b){ System.out.println(f); }*/
                
				// 是文件,判断文件名并输出文件绝对路径
                if(f.getName().toLowerCase().endsWith(".java")){
   
                    System.out.println(f);
                }
            }
        }
    }
}

二、文件搜索之文件过滤器的优化

除了上述方法,我们还可以使用过滤器来实现文件的筛选。

2.1 过滤器介绍

File 类中有两个和 ListFiles 重载的方法,方法的参数传递的就是过滤器File[] listFiles(FileFilter filter)File[] listFiles(FilenameFilter filter)

  • java.io.FileFilter 接口:用于抽象路径名(File对象)的过滤器。

    • 作用:用来过滤文件(File对象)

    • 抽象方法:用来过滤文件的方法

      boolean accept(File pathname) 测试指定抽象路径名是否应该包含在某个路径名列表中。

      • File pathname:使用 ListFiles 方法遍历目录,得到的每一个文件对象
  • java.io.FilenameFilter 接口:实现此接口的类实例可用于过滤器文件名。

    • 作用:用于过滤文件名称

    • 抽象方法:用来过滤文件的方法

      boolean accept(File dir, String name) 测试指定文件是否应该包含在某一文件列表中。

      • File dir:构造方法中传递的被遍历的目录
      • String name :使用 ListFiles 方法遍历目录,获取的每一个文件/文件夹的名称

2.2 案例分析

  • 接口作为参数,需要传递子类对象,重写其中方法。我们选择匿名内部类方式,比较简单。
  • accept方法,参数为 File,表示当前 File 下所有的子文件和子目录。保留住则返回true,过滤掉则返回false。保留规则:
    1. 要么是 .java 文件。
    2. 要么是目录,用于继续遍历。
  • 通过过滤器的作用,listFiles(FileFilter) 返回的数组元素中,子文件对象都是符合条件的,可以直接打印。

2.3 代码实现

public class DiGuiDemo4 {
   
    public static void main(String[] args) {
   
        File dir = new File("D:\\aaa");
        printDir(dir);
    }
  
    public static void printDir(File dir) {
   
      	// 匿名内部类方式,创建过滤器子类对象
        File[] files = dir.listFiles(new FileFilter() {
   
            @Override
            public boolean accept(File pathname) {
   
                return pathname.getName().endsWith(".java")||pathname.isDirectory();
            }
        });
      	// 循环打印
        for (File file : files) {
   
            if (file.isFile()) {
   
                System.out.println("文件名:" + file.getAbsolutePath());
            } else {
   
                printDir2(file);
            }
        }
    }
}   

三、文件过滤器之Lambda优化

  • 分析:FileFilter是只有一个方法的接口,因此可以用lambda表达式简写。

  • lambda格式

    ()->{ }

  • 代码实现

    public class DiGuiDemo5 {
         
        public static void main(String[] args) {
         
            File dir = new File("D:\\aaa");
            printDir(dir);
        }
    	public static void printDir(File dir) {
         
      		// lambda的改写
       		File[] files = dir.listFiles(f ->{
          
          		return f.getName().endsWith(".java") || f.isDirectory(); 
        	});
      	
    		// 循环打印
       		for (File file : files) {
         
            	if (file.isFile()) {
         
                	System.out.println("文件名:" + file.getAbsolutePath());
          		} else {
         
            		printDir3(file);
          		}
            }
        }
    }