You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java实现FTP服务器文件及目录递归遍历的问题排查

修复后的FTP递归遍历代码(解决无限循环+完整路径问题)

先上修复后的可运行代码,再逐一拆解问题根源:

package org.example;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;

import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient.connect("xxx");
            ftpClient.login("xxx", "xxx");
            ftpClient.enterLocalPassiveMode(); // 被动模式只需初始化一次
            listFolder(ftpClient, "/");
        } finally {
            // 用完务必关闭连接,避免资源泄漏
            if (ftpClient.isConnected()) {
                ftpClient.logout();
                ftpClient.disconnect();
            }
        }
    }

    private static void listFolder(FTPClient ftp, String remotePath) throws IOException {
        // 切换到目标目录,失败则直接返回
        if (!ftp.changeWorkingDirectory(remotePath)) {
            System.err.println("无法访问目录: " + remotePath);
            return;
        }

        FTPFile[] listFiles = ftp.listFiles();
        if (listFiles == null || listFiles.length == 0) {
            return;
        }

        for (FTPFile file : listFiles) {
            // 处理根目录路径拼接,避免出现//这种非法格式
            String fullPath = remotePath.equals("/") 
                ? "/" + file.getName() 
                : remotePath + "/" + file.getName();

            if (file.isDirectory()) {
                // 递归遍历子目录,传递完整路径
                listFolder(ftp, fullPath);
                // 若需要打印目录路径,取消下面注释
                // System.out.println(fullPath + "/");
            } else {
                // 打印符合要求的文件完整路径
                System.out.println(fullPath);
            }
        }
    }
}

原代码问题拆解及修复说明

1. 无限循环的核心原因

原递归调用时传递的参数是String.valueOf(listFiles[i].isDirectory()),这会把布尔值true当成目录路径传入,导致每次递归都尝试切换到名为"true"的无效目录,加上重复创建连接的混乱逻辑,最终触发无限循环。

修复:递归时传递子目录的完整路径,也就是当前路径+子目录名,确保每次递归都指向真实存在的目录。

2. 无法显示完整路径的原因

原代码仅打印文件/目录的名称,没有拼接当前所在的父路径,自然无法输出完整路径。

修复:每次循环都拼接当前路径与文件/目录名,生成fullPath,文件直接打印该路径,目录则用此路径继续递归遍历。

3. 冗余连接问题

原递归方法内重复执行connect和login,完全没必要——主方法已经建立了一次有效连接,整个递归过程复用同一个FTPClient实例即可,重复连接会浪费资源甚至触发FTP服务器的连接限制。

修复:将连接、登录、被动模式设置全部移到主方法,递归方法只负责目录遍历,最后通过finally块确保连接关闭。

4. 路径格式细节优化

当当前路径为根目录"/"时,直接拼接会出现//文件名的非法格式,通过判断处理后,确保输出路径统一为/xxx/xxx.mp4的标准格式。

内容的提问来源于stack exchange,提问作者Seomat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 00:55:14