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

序言

需要读取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());
        }
    }

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

相关推荐
我命由我123452 分钟前
MQTT - Android MQTT 编码实战(MQTT 客户端创建、MQTT 客户端事件、MQTT 客户端连接配置、MQTT 客户端主题)
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
zwz宝宝4 分钟前
第三次作业(密码学)
java·数据结构·算法
源码集结号8 分钟前
java智慧城管综合管理系统源码,前端框架:vue+element;后端框架:springboot;移动端:uniapp开发,技术前沿,可扩展性强
java·vue.js·spring boot·源代码·大数据分析·城管·电子办案
琢磨先生David20 分钟前
Java 24 深度解析:云原生时代的性能更新与安全重构
java
刘翔在线犯法1 小时前
如何在idea中写spark程序
java·spark·intellij-idea
佬乔1 小时前
JWT-验证
java·服务器·前端
编程毕设1 小时前
【含文档+PPT+源码】基于SpringBoot电脑DIY装机教程网站的设计与实现
java·spring boot·后端
不当菜虚困2 小时前
JAVA设计模式——(九)工厂模式
java·开发语言·设计模式
暖苏2 小时前
Spring中bean的生命周期(笔记)
java·spring boot·spring·spring cloud·mvc·bean生命周期·springbean
IT技术员2 小时前
【Java学习】Java的CGLIB动态代理:通俗解释与使用指南
java·开发语言·学习