多层目录按指定规则匹配获取满足要求的子目录文件


前言

目录层级扫描,精准获取指定文件目录下需要的文件。避免文件层级过深时对无关目录进行扫描。
通过提取满足逐级目录规则,达到满足最终目录后再进行文件扫描。目录规则可进行自定义,多层目录可通过分隔符间隔。
注:仅适用于文件主目录下存在多层子目录,同时有多子目录需要进行扫描文件的场景。


一、实现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 );
}

  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值