You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用Java Apache Commons Net按通配符匹配下载FTP文件

Java实现FTP批量下载匹配通配符文件的方案

嘿,我懂你现在的需求——基于已有的单文件FTP下载代码,扩展成能批量筛选并下载符合通配符规则的文件对吧?别担心,我们可以分几步轻松实现:

核心思路

  • 连接FTP服务器后,先获取目标目录下的所有文件/文件夹列表
  • 用通配符规则(比如*.txtreport_*.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()),很多防火墙环境下必须开这个,不然容易连接超时
  • 保留了你原有的单文件下载逻辑,只是封装成私有方法方便循环调用

额外注意点

  1. 确保FTP服务器允许执行LIST命令(有些服务器会限制目录列表权限)
  2. 如果需要递归下载子目录里的匹配文件,可以在代码里加递归遍历子目录的逻辑
  3. 可以根据需求加重试机制、详细日志记录,让代码更健壮

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

火山引擎 最新活动