文件过滤器

File类中有两个和listFiles重载的方法,方法的参数传递的就是过滤器。

FileFilter过滤器接口

使用FileFilter过滤器重载的方法为File[] listFiles(FileFilter filter),过滤器的详情如下:

方法 作用 参数
File[] listFiles(FileFilter filter) 它是用于抽象路径名(File对象)的过滤器,主要作用是,
用来过滤文件(File对象)
FileFilter接口内部包含一个boolean accept(File pathname),测试抽象路径名是否包含在某个路径名列表,其参数是使用listFiles方法遍历目录得到的每一个文件对象。

其中,listFiles方法一共做了两件事:

  • listFiles方法会对构造方法中传递的目录进行遍历,获取目录中的每一个文件/文件夹,并封装为File对象。
  • listFiles方法会调用参数传递的过滤器中的方法accept
  • listFiles方法会把遍历得到的每一个File对象,传递给accept方法的参数pathname

accept方法返回true时,listFiles方法就将该File对象添加到返参的File数组里。否则,不添加到返参的File数组里。

FilenameFilter过滤器接口

方法 作用 参数
File[] listFiles(FilenameFilter filter) 它的作用是用于过滤文件名 其内部包含boolean accept(File dir,String name) 测试指定文件是否包含在某一文件列表中,File dir是构造方法中传递的被遍历的目录,String name是使用istFiles方法遍历目录获取的每一个文件/文件夹名称

注意:两个过滤器接口都没有实现类,需要自行编写实现类,重写过滤的方法accept,在方法中自己定义过滤的规则。

使用FileFiter过滤器重写文件搜索

首先,我们需要实现FileFilter接口,重写其accept方法。在这个过滤方法中,对于目录我们直接返回true,让其在下一段代码中继续遍历其中的文件,对于文件,则判断是否是以.pdf结尾。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.example.demo;

import java.io.File;
import java.io.FileFilter;

public class FileFilterImpl implements FileFilter {
@Override
public boolean accept(File pathname) {
// 如果pathname是一个文件夹,则返回true,继续遍历文件夹
if(pathname.isDirectory()) {
return true;
}
return pathname.getName().toLowerCase().endsWith(".pdf");
}
}

接着,我们将FileFilterImpl实现类作为参数传递给listFiles方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.demo;

import java.io.File;

public class FileFiterDemo {

public static void main(String[] args) {
File file = new File("E:\\文档");
getAllFiles(file);
}

public static void getAllFiles(File dir) {
File[] files = dir.listFiles(new FileFilterImpl());
for (File file : files) {
if (file.isDirectory()) {
getAllFiles(file);
} else {
System.out.println(file);
}
}
}
}

运行程序,我们成功搜索出.pdf结尾的文件。

使用FilenameFilter过滤器重写文件搜索

下面,我们继续使用FilenameFilter来完成文件搜索功能。这次,我们使用匿名内部类,逻辑和刚才一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.example.demo;

import java.io.File;
import java.io.FilenameFilter;

public class FilenameFilterDemo {

public static void main(String[] args) {
File file = new File("E:\\文档");
getAllFiles(file);
}

public static void getAllFiles(File dir) {
File[] files = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// 判断其是否是文件夹或者其是否以.pdf结尾
return new File(dir, name).isDirectory() || name.toLowerCase().endsWith(".pdf");
}
});
for (File file : files) {
if (file.isDirectory()) {
getAllFiles(file);
} else {
System.out.println(file);
}
}
}
}

类似地,可以使用匿名内部类代替原有的FileFilter实现方法。

使用Lambda表达式实现文件搜索

在JDK8中,我们可以使用Lambda表达式简化代码,将上面代码中的这段代码

1
2
3
4
5
6
7
File[] files = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// 判断其是否是文件夹或者其是否以.pdf结尾
return new File(dir, name).isDirectory() || name.toLowerCase().endsWith(".pdf");
}
});

简化为:

1
File[] files = dir.listFiles((d,name)-> new File(d,name).isDirectory() || name.toLowerCase().endsWith(".pdf"));

其完整实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.example.demo;

import java.io.File;
import java.io.FilenameFilter;

public class FilenameFilterLDemo {


public static void main(String[] args) {
File file = new File("E:\\文档");
getAllFiles(file);
}

public static void getAllFiles(File dir) {
File[] files = dir.listFiles((d,name)-> new File(d,name).isDirectory() || name.toLowerCase().endsWith(".pdf"));
for (File file : files) {
if (file.isDirectory()) {
getAllFiles(file);
} else {
System.out.println(file);
}
}
}
}