8.3 综合案例

8.3.1 文件搜索

搜索D:\aaa 目录中的.java 文件。

分析:

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

代码实现:

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
public class DiGuiDemo3 {
public static void main(String[] args) {
// 创建File对象
File dir = new File("D:\\aaa");
// 调用打印目录方法
printDir(dir);
}
public static void printDir(File dir) {
// 获取子文件和目录
File[] files = dir.listFiles();
// 循环打印
for (File file : files) {
if (file.isFile()) {
// 是文件,判断文件名并输出文件绝对路径
if (file.getName().endsWith(".java")) {
System.out.println("文件名:"
+ file.getAbsolutePath());
}
} else {
// 是目录,继续遍历,形成递归
printDir(file);
}
}
}
}

8.3.2 文件过滤器优化

  java.io.FileFilterjava.io.FilenameFilter都是接口,是File的过滤器。该接口的对象可以传递给File类的listFiles(FileFilter)或者listFiles(FilenameFilter)作为参数, 接口中只有一个方法。

  • boolean accept(File pathname):FileFilter中的测试pathname是否应该包含在当前File目录中,符合则返回true。
  • boolean accept(File dir, String name):FilenameFilter中的测试dir和name组合的文件是否应该包含在目录中,符合则返回true。

分析:

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

代码实现:

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
30
31
public class DiGuiDemo4 {
public static void main(String[] args) {
File dir = new File("D:\\aaa");
printDir2(dir);
}
public static void printDir2(File dir) {
// 匿名内部类方式,创建过滤器子类对象
/*File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().toLowerCase().endsWith(".java")|| pathname.isDirectory();
}
});*/
File[] files = dir.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
//过滤规则,组合后的file是文件夹或者是.java结尾的文件返回true
return new File(dir,name).isDirectory() || name.toLowerCase().endsWith(".java");
}
});
// 循环打印
for (File file : files) {
if (file.isFile()) {
System.out.println("文件名:"
+ file.getAbsolutePath());
} else {
printDir2(file);
}
}
}
}

8.3.3 Lambda优化

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

lambda格式:

1
()‐>{ }

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
public static void printDir3(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);
}
}
}