题目
给定一个根目录,要求遍历其中的文件及子文件夹,返回所有后缀是.txt的文件List(不能使用递归)
解答
下面两个工具方法, 两个方法含义和参数含义相同, 仅仅是处理方式不同, 第一个fileDisposeByRecursion
是使用递归进行遍历文件/文件夹, 第二个fileDisposeByLoop
是使用链表进行遍历文件/文件夹,
package com.github.cosycode.common.util.io;
import com.github.cosycode.common.base.FileDisposer;
import lombok.extern.slf4j.Slf4j;
import java.io.File;
import java.io.FileFilter;
import java.util.*;
/**
* <b>Description : </b> 文件系统工具类
* <p>
* <b>created in </b> 2020/5/12
*
* @author CPF
* @since 1.0
*/
@Slf4j
public class FileSystemUtils {
private FileSystemUtils() {
}
/**
* 文件夹递归处理
* 如果 file 不能通过 fileFilter 过滤条件, 则直接返回.
* 如果 file 是一个文件, 则执行 fileDisposer 处理方法.
* 如果 file 是一个文件夹, 则对文件夹中的每个子文件夹和文件递归调用本方法.
*
* @param file 文件 或 文件夹.
* @param fileDisposer 文件处理方式.
* @param fileFilter 文件过滤器.
*/
public static void fileDisposeByRecursion(File file, FileDisposer fileDisposer, FileFilter fileFilter) {
if (file == null || !file.exists()) {
return;
}
// 过滤
if (fileFilter != null && !fileFilter.accept(file)) {
return;
}
if (file.isFile()) {
fileDisposer.dispose(file);
} else if (file.isDirectory()) {
File[] files = file.listFiles();
if (files != null) {
for (File item : files) {
fileDisposeFromDir(item, fileDisposer, fileFilter);
}
}
} else {
log.debug("非文件或文件夹, 跳过处理! filePath: {}", file.getPath());
}
}
/**
* 文件夹循环处理
* 如果 file 不能通过 fileFilter 过滤条件, 则直接返回.
* 如果 file 是一个文件, 则执行 fileDisposer 处理方法.
* 如果 file 是一个文件夹, 则对文件夹中的每个子文件夹和文件递归调用本方法.
*
* @param file 文件 或 文件夹.
* @param fileDisposer 文件处理方式.
* @param fileFilter 文件过滤器.
*/
public static void fileDisposeByLoop(File file, FileDisposer fileDisposer, FileFilter fileFilter) {
if (file == null || !file.exists()) {
return;
}
if (fileFilter != null && !fileFilter.accept(file)) {
return;
}
// 以下 file 文件 或 文件夹
for (LinkedList<File> list = new LinkedList<>(Collections.singletonList(file)); !list.isEmpty(); list.removeFirst()) {
final File first = list.getFirst();
if (first.isFile()) {
fileDisposer.dispose(first);
} else if (first.isDirectory()) {
for (File it : Optional.ofNullable(first.listFiles()).orElse(new File[]{})) {
if (fileFilter == null || fileFilter.accept(it)) {
list.add(it);
}
}
} else {
log.debug("非文件或文件夹, 跳过处理! filePath: {}", file.getPath());
return;
}
}
}
}
使用方式
给定一个根目录,要求遍历其中的文件及子文件夹,返回所有后缀是.txt的文件List(不能使用递归)
根据题意: 使用fileDisposeByLoop
方法,
- 第一个参数输入需要递归的文件夹,
- 第二个参数负责对符合条件的文件进行处理, 这里我们直接将其添加到list中
- 第三个参数负责文件的过滤, 这个过滤是同时可以过滤文件或文件夹, 这里我们过滤出文件夹或以
.txt
结尾的文件.
public static void main(String[] args) {
// 指定的文件夹
final File file = new File("D:\\doc\\");
// 存放所有后缀是.txt的文件List
List<File> list = new ArrayList<>();
fileDisposeByLoop(file, list::add, f -> f.isDirectory() || (f.isFile() && f.getName().endsWith(".txt")));
// 返回所有后缀是.txt的文件List
list.forEach(System.out::println);
}