如何使用Java Apache Commons Net按通配符匹配下载FTP文件
Java实现FTP批量下载匹配通配符文件的方案
嘿,我懂你现在的需求——基于已有的单文件FTP下载代码,扩展成能批量筛选并下载符合通配符规则的文件对吧?别担心,我们可以分几步轻松实现:
核心思路
- 连接FTP服务器后,先获取目标目录下的所有文件/文件夹列表
- 用通配符规则(比如
*.txt、report_*.pdf)过滤出需要下载的文件 - 循环调用你已有的单文件下载逻辑,批量处理匹配到的文件
完整实现代码示例
我把你提供的单文件下载逻辑补全并整合到批量下载的代码里了:
import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; public class FTPWildcardDownloader { // 单文件下载方法(基于你的代码扩展) private static void downloadSingleFile(FTPClient ftpClient, String remoteFilePath, String localDir) throws IOException { File localFile = new File(localDir + File.separator + new File(remoteFilePath).getName()); try (BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(localFile))) { if (!ftpClient.retrieveFile(remoteFilePath, outputStream)) { System.out.println("下载文件失败: " + remoteFilePath); } } } // 批量下载匹配通配符的文件 public static void downloadWildcardFiles(String server, int port, String user, String pass, String remoteDir, String wildcardPattern, String localDir) throws IOException { FTPClient ftpClient = new FTPClient(); try { // 连接FTP服务器 ftpClient.connect(server, port); ftpClient.login(user, pass); ftpClient.enterLocalPassiveMode(); ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE); // 切换到目标远程目录 if (!ftpClient.changeWorkingDirectory(remoteDir)) { System.out.println("远程目录不存在: " + remoteDir); return; } // 获取目录下的所有文件 FTPFile[] files = ftpClient.listFiles(); if (files == null || files.length == 0) { System.out.println("远程目录下没有文件"); return; } // 创建本地目录(如果不存在) File localDirectory = new File(localDir); if (!localDirectory.exists()) { localDirectory.mkdirs(); } // 遍历文件,匹配通配符并下载 for (FTPFile file : files) { if (!file.isFile()) { continue; // 跳过文件夹 } String fileName = file.getName(); // 把通配符转成正则表达式匹配 String regexPattern = wildcardPattern.replace("*", ".*").replace("?", "."); if (fileName.matches(regexPattern)) { System.out.println("开始下载: " + fileName); downloadSingleFile(ftpClient, remoteDir + "/" + fileName, localDir); System.out.println("下载完成: " + fileName); } } } finally { // 断开连接 if (ftpClient.isConnected()) { ftpClient.logout(); ftpClient.disconnect(); } } } // 测试主方法 public static void main(String[] args) { String server = "your-ftp-server.com"; int port = 21; String user = "your-username"; String pass = "your-password"; String remoteDir = "/remote/files/dir"; String wildcardPattern = "*.txt"; // 示例:下载所有txt文件 String localDir = "./local/downloads"; try { downloadWildcardFiles(server, port, user, pass, remoteDir, wildcardPattern, localDir); System.out.println("批量下载任务完成"); } catch (IOException e) { e.printStackTrace(); } } }
关键细节说明
- 这里用了Apache Commons Net库的
FTPClient,这是Java处理FTP操作最常用的工具,Maven项目可以加依赖:<dependency><groupId>commons-net</groupId><artifactId>commons-net</artifactId><version>3.9.0</version></dependency> - 通配符转正则的逻辑:把
*换成.*(匹配任意长度字符),?换成.(匹配单个字符),这样就能用Java原生的String.matches()做匹配 - 加入了被动模式(
enterLocalPassiveMode()),很多防火墙环境下必须开这个,不然容易连接超时 - 保留了你原有的单文件下载逻辑,只是封装成私有方法方便循环调用
额外注意点
- 确保FTP服务器允许执行LIST命令(有些服务器会限制目录列表权限)
- 如果需要递归下载子目录里的匹配文件,可以在代码里加递归遍历子目录的逻辑
- 可以根据需求加重试机制、详细日志记录,让代码更健壮
内容的提问来源于stack exchange,提问作者Karthik Deepan




