package org.springside.modules.utils.io;
import java.io.File;
import java.util.List;
import java.util.regex.Pattern;
import org.springside.modules.utils.text.WildcardMatcher;
import com.google.common.base.Predicate;
import com.google.common.collect.TreeTraverser;
import com.google.common.io.Files;
public class FileTreeWalker {
/**
* 前序递归列出所有文件, 包含文件与目录,及根目录本身.
*
* 前序即先列出父目录,在列出子目录. 如要后序遍历, 直接使用Files.fileTreeTraverser()
*/
public static List<File> listAll(File rootDir) {
return Files.fileTreeTraverser().preOrderTraversal(rootDir).toList();
}
/**
* 前序递归列出所有文件, 只包含文件.
*/
public static List<File> listFile(File rootDir) {
return Files.fileTreeTraverser().preOrderTraversal(rootDir).filter(Files.isFile()).toList();
}
/**
* 前序递归列出所有文件, 列出后缀名匹配的文件. (后缀名不包含.)
*/
public static List<File> listFileWithExtension(final File rootDir, final String extension) {
return Files.fileTreeTraverser().preOrderTraversal(rootDir).filter(new FileExtensionFilter(extension)).toList();
}
/**
* 前序递归列出所有文件, 列出文件名匹配通配符的文件
*
* 如 ("/a/b/hello.txt", "he*") 将被返回
*/
public static List<File> listFileWithWildcardFileName(final File rootDir, final String fileNamePattern) {
return Files.fileTreeTraverser().preOrderTraversal(rootDir).filter(new WildcardFileNameFilter(fileNamePattern))
.toList();
}
/**
* 前序递归列出所有文件, 列出文件名匹配正则表达式的文件
*
* 如 ("/a/b/hello.txt", "he.*\.text") 将被返回
*/
public static List<File> listFileWithRegexFileName(final File rootDir, final String regexFileNamePattern) {
return Files.fileTreeTraverser().preOrderTraversal(rootDir)
.filter(new RegexFileNameFilter(regexFileNamePattern)).toList();
}
/**
* 前序递归列出所有文件, 列出符合ant path风格表达式的文件
*
* 如 ("/a/b/hello.txt", "he.*\.text") 将被返回
*/
public static List<File> listFileWithAntPath(final File rootDir, final String antPathPattern) {
return Files.fileTreeTraverser().preOrderTraversal(rootDir)
.filter(new AntPathFilter(FilePathUtil.contact(rootDir.getAbsolutePath(), antPathPattern))).toList();
}
/**
* 直接使用Guava的TreeTraverser,获得更大的灵活度, 比如加入各类filter,前序/后序的选择,一边遍历一边操作
*
* <pre>
* FileUtil.fileTreeTraverser().preOrderTraversal(root).iterator();
* </pre>
*/
public static TreeTraverser<File> fileTreeTraverser() {
return Files.fileTreeTraverser();
}
/**
* 以文件名正则表达式为filter,配合fileTreeTraverser使用
*/
public static final class RegexFileNameFilter implements Predicate<File> {
private final Pattern pattern;
private RegexFileNameFilter(String pattern) {
this.pattern = Pattern.compile(pattern);
}
@Override
public boolean apply(File input) {
return input.isFile() && pattern.matcher(input.getName()).matches();
}
}
/**
* 以文件名通配符为filter,配合fileTreeTraverser使用.
*
* @param pattern 支持*与?的通配符,如hello*.txt 匹配 helloworld.txt
*/
public static final class WildcardFileNameFilter implements Predicate<File> {
private final String pattern;
private WildcardFileNameFilter(String pattern) {
this.pattern = pattern;
}
@Override
public boolean apply(File input) {
return input.isFile() && WildcardMatcher.match(input.getName(), pattern);
}
}
/**
* 以文件名后缀做filter,配合fileTreeTraverser使用
*/
public static final class FileExtensionFilter implements Predicate<File> {
private final String extension;
private FileExtensionFilter(String extension) {
this.extension = extension;
}
@Override
public boolean apply(File input) {
return input.isFile() && extension.equals(FileUtil.getFileExtension(input));
}
}
/**
* 以ant风格的path为filter,配合fileTreeTraverser使用.
*
* @param pattern 支持ant风格的通配符,如/var/?/a?.txt 匹配 /var/b/ab.txt, 其他通配符包括**,*
*/
public static final class AntPathFilter implements Predicate<File> {
private final String pattern;
private AntPathFilter(String pattern) {
this.pattern = pattern;
}
@Override
public boolean apply(File input) {
return input.isFile() && WildcardMatcher.matchPath(input.getAbsolutePath(), pattern);
}
}
}