递归读取指定目录下的文件

序言

需要读取sftp服务器上符合指定的文件名正则的文件列表,目前想到的最好的办法就是递归。

我这里引入的依赖是:

xml 复制代码
        <!--   jsch-sftp连接     -->
        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.54</version>
        </dependency>

不废话直接上代码:

java 复制代码
  public static List<String> getFileList(ChannelSftp channelSftp, String path, String fileNamePattern, Integer filePathDepth) {
        List<String> fileList = Lists.newLinkedList();
        try {
            Pattern pattern = Pattern.compile(fileNamePattern);
            Vector<ChannelSftp.LsEntry> files = channelSftp.ls(path);
            //读取的根路径下一级就是文件
            if (1 == filePathDepth) {
                for (ChannelSftp.LsEntry entry : files) {
                    String fileName = entry.getFilename();
                    //找到和规则(文件名正则)匹配的文件
                    if (pattern.matcher(fileName).matches()) {
                       //拼接全路径
                        String fullPath = path + fileName;
                        fileList.add(fullPath);
                    }
                }
            } else {
                //从读取根路径下开始算目录深度时,目录深度大于1就使用递归来读取文件列表
                manyDirFileList(channelSftp, path, fileNamePattern, fileList, bComFilesaveReadruleDO.getDirPattern());
            }
        } catch (Exception e) {
            log.error("获取sftp指定目录下的文件列表失败,{}", e.getMessage());
        }
        return fileList;
    }


/**
     * 递归获取提供的路径下多级目录下符合正则的所有文件
     *
     * @param channelSftp ftp对象
     * @param path        路径
     * @param fileList    文件列表
     **/
    public static void manyDirFileList(ChannelSftp channelSftp, String path, String fileNamePattern,
                                       List<String> fileList, String dirPattern) throws Exception {
        try {
            List<Pattern> dirPatterns = new ArrayList<>();
            if (StringUtils.isNotEmpty(dirPattern)) {
                for (String pat : dirPattern.split(",")) {
                    dirPatterns.add(Pattern.compile(pat.trim()));
                }
            }
            Pattern fileNamePat = Pattern.compile(fileNamePattern);

            if (isDirectory(channelSftp, path)) {
                Vector<?> vector = channelSftp.ls(path);
                for (Object l : vector) {
                    ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) l;
                    String fileName = file.getFilename();
                    boolean isDirMatch = dirPatterns.isEmpty();
                    for (Pattern dirPat : dirPatterns) {
                        if (dirPat.matcher(fileName).matches()) {
                            isDirMatch = true;
                            break;
                        }
                    }
                    if (fileName.equals(".") || fileName.equals("..")) {
                        continue;
                    }
                    if (isDirMatch || fileNamePat.matcher(fileName).matches()) {
                        String fullPath = path + fileName + (file.getAttrs().isDir() ? "/" : "");
                        manyDirFileList(channelSftp, fullPath, fileNamePattern, fileList, dirPattern);
                    }
                }
            } else {
                String fileName = path.substring(path.lastIndexOf("/") + 1);
                if (fileNamePat.matcher(fileName).matches()) {
                    fileList.add(path);
                }
            }
        } catch (SftpException e) {
            log.error("获取FTP指定目录下的文件异常,路径:{},异常信息:{}", path, e.getMessage());
        } catch (Exception e) {
            log.error("递归获取SFTP指定目录下的文件列表失败,路径:{},异常信息:{}", path, e.getMessage());
            throw new Exception("递归获取SFTP指定目录下的文件列表失败,路径:" + path + ",异常信息:" + e.getMessage());
        }
    }

另外还有一个需求就是只读取10个文件:

java 复制代码
 public static List<String> getFileListFor10(ChannelSftp channelSftp,  String path, String fileNamePattern, Integer filePathDepth) {
        List<String> fileList = Lists.newLinkedList();
        try {
            Pattern pattern = Pattern.compile(fileNamePattern);
            Vector<ChannelSftp.LsEntry> files = channelSftp.ls(path);
            //读取的根路径下一级就是文件
            if (1 == filePathDepth) {
                for (ChannelSftp.LsEntry entry : files) {
                    if (fileList.size() > 10) {
                        log.info("已读取10个文件,不再读取目录:{}下的文件", path);
                        break;
                    }
                    String fileName = entry.getFilename();
                    //找到和规则(文件名正则)匹配的文件
                    if (pattern.matcher(fileName).matches()) {
                        //拼接全路径
                        String fullPath = path + fileName;
                        fileList.add(fullPath);
                    }
                }
            } else {
                //从输入的根路径下开始算目录深度时,目录深度大于1就使用递归来读取文件列表
                manyDirFileListFor10(channelSftp, path, fileNamePattern, fileList, bComFilesaveReadruleDO.getDirPattern());
            }
        } catch (Exception e) {
            log.error("获取sftp指定目录下的文件列表失败,{}", e.getMessage());
        }
        return fileList;
    }

/**
     * 递归获取提供的路径下多级目录下符合正则的前10个文件
     *
     * @param channelSftp ftp对象
     * @param path        路径
     * @param fileList    文件列表
     **/
    public static void manyDirFileListFor10(ChannelSftp channelSftp, String path, String fileNamePattern,
                                       List<String> fileList, String dirPattern) {
        try {
            List<Pattern> dirPatterns = new ArrayList<>();
            if (StringUtils.isNotEmpty(dirPattern)) {
                for (String pat : dirPattern.split(",")) {
                    dirPatterns.add(Pattern.compile(pat.trim()));
                }
            }
            Pattern fileNamePat = Pattern.compile(fileNamePattern);

            if (isDirectory(channelSftp, path)) {
                Vector<?> vector = channelSftp.ls(path);
                for (Object o : vector) {
                    // 如果已经找到了10个文件,直接返回,不再递归
                    if (fileList.size() >= 10) {
                        log.info("已读取10个文件,不再读取目录:{}下的文件", path);
                        break;
                    }
                    ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) o;
                    String fileName = file.getFilename();
                    boolean isDirMatch = dirPatterns.isEmpty();
                    for (Pattern dirPat : dirPatterns) {
                        if (dirPat.matcher(fileName).matches()) {
                            isDirMatch = true;
                            break;
                        }
                    }
                    if (fileName.equals(".") || fileName.equals("..")) {
                        continue;
                    }
                    if (isDirMatch || fileNamePat.matcher(fileName).matches()) {
                        String fullPath = path + fileName + (file.getAttrs().isDir() ? "/" : "");
                        manyDirFileListFor10(channelSftp, fullPath, fileNamePattern, fileList, dirPattern);
                    }
                }
            } else {
                String fileName = path.substring(path.lastIndexOf("/") + 1);
                if (fileNamePat.matcher(fileName).matches()) {
                    fileList.add(path);
                }
            }
        } catch (SftpException e) {
            log.error("获取FTP指定目录下的文件异常,路径:{},异常信息:{}", path, e.getMessage());
        } catch (Exception e) {
            log.error("递归获取SFTP指定目录下的文件列表失败,路径:{},异常信息:{}", path, e.getMessage());
        }
    }

-----------------知道的越多, 不知道的越多--------------------

相关推荐
阿达King哥10 分钟前
在Windows11下编译openjdk 21
java·jvm
shark-chili31 分钟前
从操作系统底层浅谈程序栈的高效性
java
不知疲倦的仄仄1 小时前
第二天:深入理解 Selector:单线程高效管理多个 Channel
java·nio
期待のcode1 小时前
Java虚拟机栈
java·开发语言·jvm
珂朵莉MM1 小时前
全球校园人工智能算法精英大赛-产业命题赛-算法巅峰赛 2025年度画像
java·人工智能·算法·机器人
芒克芒克1 小时前
本地部署SpringBoot项目
java·spring boot·spring
cute_ming1 小时前
关于基于nodeMap重构DOM的最佳实践
java·javascript·重构
sww_10261 小时前
Netty原理分析
java·网络
小突突突1 小时前
Spring框架中的单例bean是线程安全的吗?
java·后端·spring
Mr.Entropy2 小时前
JdbcTemplate 性能好,但 Hibernate 生产力高。 如何选择?
java·后端·hibernate