在第一章中,有一个练习使用递归搜索文件
1 public static void main(String[] args) { 2 File f=new File("E:\\aaa"); 3 method(f); 4 } 5 6 private static void method(File f) { 7 System.out.println(f.getAbsoluteFile()); 8 File[] files = f.listFiles(); 9 for (File file : files) { 10 if(file.isDirectory()){ 11 method(file); 12 }else{ 13 if(f.getName()..toLowerCase().endWith(".java")){ 14 System.out.println(file); 15 } 16 } 17 } 18 }
可以使用过滤器来查找文件。
第二章、过滤器
- 在File类中有两个和ListFiles重载的方法,方法的参数就是过滤器
- File[] listFiles(FileFilter filter):
- java.io.fileFilter接口:用于抽象路径名(File对象)的过滤器
- 作用:用来过滤文件(File对象)【接口中只有一个方法】
- 抽象方法:用来过滤文件的方法
- boolean accept(File pathname)测试指定抽象路径名是否应该包含在某个路径名列表中。
- File pathname:使用ListFiles方法遍历目录,得到的每一个文件对象
- 抽象方法:用来过滤文件的方法
- File[] listFiles(FilenameFilter filter):
- java.io.FilenameFilter接口:实现此类的实例可以用于每一个过滤文件名。
- 作用:用来过滤文件名称
- 抽象方法:用来过滤文件的方法
- boolean accept(File dir,String name):测试指定文件是否应该包含在某一个文件列表中。
-
参数:
-
File dir:构造方法中传递的被遍历的目录
-
String name: 使用listFiles方法遍历目录,得到的每一个文件/文件夹的名称
-
- java.io.FilenameFilter接口:实现此类的实例可以用于每一个过滤文件名。
-
注意:两个过滤器接口都是没有实现类的,需要我们自己重写实现类,重写过滤的方法accept,在方法中自己定义过滤的规则。
- 自定义规则为return true
1 //1.创建FileFilter 接口的实现类,重写accept 方法,自定义过滤规则 2 import java.io.File; 3 import java.io.FileFilter; 4 5 public class FileFilterImpl implements FileFilter { 6 @Override 7 public boolean accept(File pathname) { 8 return true; 9 } 10 } 11 12 public static void main(String[] args) { 13 File f=new File("E:\\aaa"); 14 method(f); 15 } 16 17 private static void method(File f) { 18 System.out.println(f.getAbsoluteFile()); 19 File[] files = f.listFiles(new FileFilterImpl());//2.传递过滤器对象 20 for (File file : files) { 21 if(file.isDirectory()){ 22 method(file); 23 }else{ 24 System.out.println(file); 25 } 26 } 27 }
- 但是结果并没有完成过滤
- 自定义规则为return true
- 需要明确FileFilter的原理以及如何使用
1 public class FileFilterImpl implements FileFilter {
2 @Override
3 public boolean accept(File pathname) {
4 return pathname.getName().toLowerCase().endsWith(".java");
5 }
6 }
运行结果,将文件夹也过滤掉了,文件夹里面的.java文件也一起遗漏了。改为:
1 public class FileFilterImpl implements FileFilter {
2 @Override
3 public boolean accept(File pathname) {
4 //如果pathname是一个文件夹,返回true,继续遍历这个文件
5 if(pathname.isDirectory()){
6 return true;
7 }
8 return pathname.getName().toLowerCase().endsWith(".java");
9 }
10 }
运行结果是想要的。优化为匿名内部类:
1 private static void method(File f) {
2 System.out.println(f.getAbsoluteFile());
3 File[] files = f.listFiles(new FileFilter() {
4 @Override
5 public boolean accept(File pathname) {
6 if(pathname.isDirectory()){
7 return true;
8 }
9 return pathname.getName().toLowerCase().endsWith(".java");
10 }
11 });
12 for (File file : files) {
13 if(file.isDirectory()){
14 method(file);
15 }else{
16 System.out.println(file);
17 }
18 }
19 }
另外一种过滤器 File[] listFiles(FilenameFilter filter) 也可以使用匿名内部类
File[] files1=f.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return new File(dir,name).isDirectory()||name.toLowerCase().endsWith(".java");
}
});
这两种接口比较特殊,都是只有一个方法,所以可以使用Lambda 表达式进一步优化
//使用Lambda 表达式
File[] files3=f.listFiles(pathname->pathname.isDirectory()||pathname.getName().toLowerCase().endsWith(".java"));
//使用Lambda表达式
File[] files2=f.listFiles((dir,name)->new File(dir,name).isDirectory()||name.toLowerCase().endsWith(".java"));