遍历目录下的文件
File类中有一个list()方法,该方法用于遍历某个指定目录下的所有文件的名称,接下来通过一个案例来演示list()方法的使用,如文件1所示。
文件1 Example13.java
1 import java.io.File;
2 import java.util.Arrays;
3 public class Example13 {
4 public static void main(String[] args) {
5 // 创建File对象,并指定文件路径
6 File file = new File("F:\\Java基础入门\\workspace\\chapter07");
7 // 判断是否是目录
8 if (file.isDirectory()) {
9 // 获取目录中的所有文件的名称
10 String[] fileNames = file.list();
11 // 对指定路径下的文件或目录进行遍历
12 Arrays.stream(fileNames)
13 .forEach(f -> System.out.println(f));
14 }
15 }
16 }
运行结果如图1所示。
图1 运行结果
在文件1中,创建了一个File对象,并指定了一个路径“F:\Java基础入门\workspace\chapter07”(本章项目存放在本地磁盘路径,读者在进行测试时可自行指定),通过调用File的isDirectory()方法判断路径指向是否为目录,如果是目录就调用list()方法,获得一个String类型的数组fileNames,数组中包含这个目录下所有文件的文件名(包括文件和文件夹名称)。接着通过数组工具类Arrays的stream()方法将数组先转换为Stream流并进行遍历,依次打印出每个文件的文件名。
虽然上使用list()方法可以遍历某个目录下的所有文件,但有时只需要获取指定类型的文件,如获取指定目录下所有的“.txt”文件。针对这种需求,File类中提供了一个重载的list(FilenameFilter filter)方法,该方法接收一个FilenameFilter接口类型的参数。FilenameFilter是一个函数式接口,被称作文件过滤器,接口中定义了一个抽象方法accept(File dir,String name)用于依次对指定File的所有子目录或文件进行迭代。在调用list(FilenameFilter filter)方法时,需要实现文件过滤器FilenameFilter,并在accept(File dir,String name)方法中进行筛选,从而获得指定类型的文件。
接下来,在上一个案例基础上来演示如何筛选遍历指该目录下所有扩展名为“.txt”的文件,如文件2所示。
文件2 Example14.java
1 import java.io.*;
2 import java.util.Arrays;
3 public class Example14 {
4 public static void main(String[] args){
5 // 创建File对象,并指定文件路径
6 File file = new File("F:\\Java基础入门\\workspace\\chapter07");
7 // 判断是否是目录
8 if (file.isDirectory()) {
9 // 使用Lambda表达式过滤目录中所有以.txt结尾的文件的名称
10 String[] fileNames = file.list(
11 (dir,name) -> name.endsWith(".txt"));
12 // 对指定路径下的文件或目录进行遍历
13 Arrays.stream(fileNames)
14 .forEach(f -> System.out.println(f));
15 }
16 }
17 }
运行结果如图2所示。
图2 运行结果
在文件2中,在第10~11行代码中调用list(FilenameFilter filter)方法时传入了一个Lambda表达式形式的参数,该参数实现了函数式接口filenameFilter中的accept(File dir,String name)方法,对目录下的文件进行过滤,筛选出所有以“.txt”结尾的文件,然后使用数组工具类Arrays的stream()方法将数组先转换为Stream流并进行遍历,打印出筛选结果。
有时候在一个目录下,除了文件还有子目录,如果想得到所有子目录下的File类型对象,list()方法显然不能满足要求,这时需要使用File类提供的另一个方法listFiles()。listFiles()方法返回一个File对象数组,当对数组中的元素进行遍历时,如果元素中还有子目录需要遍历,则可以使用递归再次遍历子目录。
接下来通过一个案例来实现遍历指定目录下的文件,如文件3所示。
文件3 Example15.java
1 import java.io.*;
2 public class Example15 {
3 public static void main(String[] args){
4 // 创建File对象,并指定文件路径
5 File file = new File(" F:\\Java基础入门\\workspace\\chapter07");
6 // 调用fileDir()方法,遍历目录
7 fileDir(file);
8 }
9 // 遍历目录及其子目录
10 public static void fileDir(File file) {
11 // 获得目录下所有文件,并赋给数组
12 File[] listFiles = file.listFiles();
13 // 循环遍历数组
14 for (File files : listFiles) {
15 // 如果遍历的是目录,则递归调用fileDir()方法
16 if(files.isDirectory()){
17 fileDir(files);
18 }
19 // 输出文件路径
20 System.out.println(files);
21 }
22 }
23 }
运行结果如图3所示。
图3 运行结果
在文件3中,定义了一个静态方法fileDir(),该方法接收一个表示目录的File对象。在方法中,首先通过调用listFiles()方法把该目录下所有的子目录和文件存到一个File类型的数组listFiles中,接着遍历数组listFiles,并对当前遍历的File对象进行判断,如果是目录就递归调用fileDir()方法进行子目录遍历,如果是文件就直接打印输出文件的路径,这样该目录下的所有文件就被成功遍历出来了。