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
相关产品推荐
相关产品推荐

