博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

文件过滤器

Posted on 2020-08-08 21:12  池塘鱼  阅读(484)  评论(0)    收藏  举报

一、引言

java.io.File 类有两个方法可以遍历文件数组,分别是list()和listFiles(),前者返回相对路径的字符串数组,后者返回绝对路径的File数组。

如果要实现文件搜索功能,如在D盘的某个文件夹下搜索".java"结尾的文件,就需要用到遍历方法,辅以文件名判断。代码见下:

package com.ex.file;

import java.io.File;
import java.util.LinkedList;
import java.util.List;


public class SearchTest {
    public static void main(String[] args) {
        //初始化参数,给参数赋值
        File dir=new File("D:\\IntelliJ IDEA 2017\\work\\algorithmPro");
        String str=".java";
        LinkedList<File> files=new LinkedList<>();
        //搜索
        search(dir,str,files);
        //输出结果
        for (File file : files) {
            System.out.println(file);
        }
    }

    //遍历指定目录,搜索以指定字符串结尾的文件,添加到List数组里
    public static void search(File dir, String str, List<File> files) {
        File[] dirs = dir.listFiles();
        for (int i = 0; i < dirs.length; i++) {
            if (dirs[i].isFile()) {
                if (dirs[i].getName().endsWith(str)) {//过滤文件
                    files.add(dirs[i]);
                }
            }else {
                search(dirs[i],str,files);
            }
        }
    }


}
这是其中一种方法,当然也有别的方法,比如使用list()和listFiles()的重载方法:

 


 其中的参数FileFilterFilenameFilter就是文件过滤器。

 

二、过滤器介绍

  1.FileFilter

  抽象路径名的过滤器,此接口的实例可以传递到 listFiles(FileFilter)方法的File文件。

  该过滤器是一个没有实现类的接口,只有一个抽象方法 boolean accept(File pathname),是函数式接口,支持Lambda表达式创建匿名对象作为参数。

  方法 boolean accept(File pathname) 负责测试指定的抽象路径名是否应包含在路径名列表中,由用户根据自己的需求重写。

 

  2.FilenameFilter

  用于实现此接口的类的实例用于过滤文件名,此接口的实例用在过滤 list(FilenameFilter)或 listFiles(FilenameFilter) 返回的目录/文件列表。

  同样是一个没有实现类的接口,只有一个抽象方法 boolean accept(File dir, String name),根据自己的需要重写。

   如果要用文件过滤器,list()我不太常用,还是比较常用listFiles()方法,因为:

    • 如果是只对当前层级的文件进行搜索,可以使用list(FilenameFilter),判断一个抽象路径名是文件还是目录只需构造一个File对象然后调用判断方法即可。
public void findFiles(File dir, String str) {
        String[] files = dir.list((dirr, name) -> new File(dirr, name).isFile() && name.endsWith(str));
        for (String val:files) {
            System.out.println(val);
        }
    }
    • 但如果需要递归子目录,就不可以了,因为返回的抽象路径名的字符串数组是相对路径,如果要递归子目录查找文件,只能获取到传入的参数指定的路径,无法构造完整的路径,会造成空指针异常。

 

三、使用过滤器实现文件搜索的代码示例

package com.ex.file;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

public class FileFilterTest {
    public static void main(String[] args) {
        File dir = new File("D:\\IntelliJ IDEA 2017\\work\\algorithmPro\\03_IO");
        LinkedList<File> list=new LinkedList<>();
        String str=".java";
        findFiles(dir,str,list);
        for (File file :list) {
            System.out.println(file);
        }
    }

    public static void findFiles(File dir, String str, List<File> list) {
        //过滤掉非.java结尾的文件:如果是目录 或 是以.java结尾的文件就加入文件列表
        File[] files = dir.listFiles((file) -> file.isDirectory() || file.getName().endsWith(str));
//        File[] files = dir.listFiles((dirr,name) -> new File(dirr,name).isDirectory() || name.endsWith(str));
        //对每个File进行遍历,如果是文件就加入,因为过滤器保证剩下的文件都是符合条件的,如果是目录则需要递归遍历
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()){
                list.add(files[i]);
            }else {
                findFiles(files[i],str,list);
            }
        }

    }
}