前言
目录层级扫描,精准获取指定文件目录下需要的文件。避免文件层级过深时对无关目录进行扫描。
通过提取满足逐级目录规则,达到满足最终目录后再进行文件扫描。目录规则可进行自定义,多层目录可通过分隔符间隔。
注:仅适用于文件主目录下存在多层子目录,同时有多子目录需要进行扫描文件的场景。
一、实现FileFilter
此FileFilter 对规则进行处理,并根据层级规则获取满足要求的文件目录,当层级大于规则设置深度要求时默认不符合扫描要求。
代码如下(示例):
public class DirRegexFilter implements FileFilter {
private static final String SPLIT_STRING_DIRECTORY = "#";
private final String[] regexs;
private final int maxDepth;
private int index;
public DirRegexFilter(String regex) {
this.regexs = regex.split(SPLIT_STRING_DIRECTORY);
this.maxDepth = regexArray.length;
}
public void setIndex(int index) {
this.index = index;
}
public boolean validDepth() {
return this.index == this.maxDepth - 1;
}
@Override
public boolean accept(File rootFile) {
if (index >= maxDepth) {
return false;
}
return rootFile.isDirectory() && Pattern.compile(regexs[index]).matcher(rootFile.getName()).find();
}
}
二、扫描主要逻辑
通过指定扫描“主目录”、“子目录规则”进行文件目录扫描,先获取满足要求的最终目录,再获取指定目录下文件。
子目录规则设置如下:
AA.* : 一层子目录 AA开头的文件夹
AA.#. : 二层子目录,第一层子目录 AA开头的文件夹,第二层通配(也可指定规则,满足正则即可)
注:多层使用 “#” 间隔并增加正则即可,同时目录规则逐级匹配。必须完全符合层级要求。
代码如下(示例):
@Slf4j
public class RegexDirectoryScanner {
public List<File> scannerFiles(String rootDirectory, String subRegex ) {
File rootFile = new File(rootDirectory);
if(rootFile.isDirectory()) {
List<File> fileList = new ArrayList<>();
DirRegexFilter fileFilter = new DirRegexFilter(subRegex );
List<File> directoryList = getRegexDirectory(rootFile,fileFilter,0);
for (File subDirectory : directoryList){
File[] files = subDirectory.listFiles(File::isFile);
if(requireNonNull(files).length > 0){
log.debug("目录:{}扫描到文件数量{}",subDirectory.getPath(),files.length);
fileList.addAll(Arrays.asList(files));
} else {
log.debug("目录:{}未扫描到文件",subDirectory.getPath());
}
}
log.info("目录:{}共扫描到文件数量{}",rootDirectory,fileList.size());
return fileList;
}
return Collections.emptyList();
}
public List<File> getRegexDirectory(File rootFile, final DirRegexFilter filter, int findIndex) {
List<File> fileList = new ArrayList<>();
if (rootFile.isDirectory()) {
if(log.isTraceEnabled()) {
log.trace("目录:{} 层级:{}",rootFile.getPath(),findIndex);
}
filter.setIndex(findIndex);
File[] files = rootFile.listFiles(filter);
if(filter.validDepth()) {
fileList.addAll(asList(requireNonNull(files)));
}
for (File subDir : requireNonNull(files)) {
findIndex ++;
fileList.addAll(getRegexDirectory(subDir, filter,findIndex));
findIndex --;
}
}
return fileList;
}
}
三、mian内容
public static void main(String[] args) {
String rootPath = "D:\\abc";
String regex = "AA.*#.*#.*AA.*";
List<File> fileList = new RegexDirectoryScanner ().scannerFiles(rootPath,regex );
}