一、引言
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()的重载方法:

其中的参数FileFilter和FilenameFilter就是文件过滤器。
二、过滤器介绍
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); } } } }
浙公网安备 33010602011771号