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

如何在Java中通过通配符路径模式仅列出S3中匹配规则的文件

Java实现S3通配符路径匹配文件的方案

首先明确:AWS S3本身的原生API不直接支持通配符、正则匹配过滤对象,所有筛选逻辑都需要先拉取指定前缀下的对象列表,再在本地做模式匹配,以下是可直接落地的实现方案:

方案1:AWS SDK for Java + 正则匹配(最通用方案)

步骤如下:

  • 首先拆分路径模式,提取固定前缀缩小S3拉取范围:你给出的模式s3://dataai/alarms/Json/mydata/[0-9]*/[0-9]*/[0-9]*/*_01.json的固定前缀是s3://dataai/alarms/Json/mydata/,只拉取该前缀下的所有对象,避免拉取无关文件减少IO开销
  • 将通配符模式转为Java正则表达式:[0-9]*对应正则\d*,*对应正则[^/]*(避免跨目录匹配),最终转换后的正则为^alarms/Json/mydata/\d*/\d*/\d*/[^/]*_01\.json$(注意S3对象key不带bucket名,所以正则里去掉开头的s3://dataai/)
  • 调用S3 ListObjectsV2 API拉取指定前缀下的所有对象,遍历每个对象的key用正则匹配,符合规则的就保留

示例代码片段

import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

public class S3WildcardMatcher {
    public static void main(String[] args) {
        S3Client s3Client = S3Client.create();
        String bucketName = "dataai";
        String fixedPrefix = "alarms/Json/mydata/";
        // 转换后的正则表达式
        Pattern pattern = Pattern.compile("^alarms/Json/mydata/\\d*/\\d*/\\d*/[^/]*_01\\.json$");
        List<String> matchedKeys = new ArrayList<>();

        ListObjectsV2Request request = ListObjectsV2Request.builder()
                .bucket(bucketName)
                .prefix(fixedPrefix)
                .build();

        ListObjectsV2Iterable response = s3Client.listObjectsV2Paginator(request);
        for (S3Object s3Object : response.contents()) {
            String key = s3Object.key();
            if (pattern.matcher(key).matches()) {
                matchedKeys.add("s3://" + bucketName + "/" + key);
            }
        }

        // 输出匹配结果
        matchedKeys.forEach(System.out::println);
    }
}

方案2:Hadoop AWS库(适合已有Hadoop依赖的项目)

如果你的项目已经引入了Hadoop相关依赖,可以直接用org.apache.hadoop.fs.s3a.S3AFileSystem提供的globStatus方法,原生支持通配符路径匹配,不用自己写正则转换逻辑,示例用法:

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.s3a.S3AFileSystem;
import java.net.URI;

public class S3HadoopMatcher {
    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        S3AFileSystem fs = new S3AFileSystem();
        fs.initialize(URI.create("s3://dataai/"), conf);
        // 直接传入通配符路径即可
        FileStatus[] statuses = fs.globStatus(new Path("s3://dataai/alarms/Json/mydata/[0-9]*/[0-9]*/[0-9]*/*_01.json"));
        for (FileStatus status : statuses) {
            System.out.println(status.getPath().toString());
        }
        fs.close();
    }
}

注意该方案依赖Hadoop AWS包,需要在pom中引入对应版本的hadoop-aws和hadoop-common依赖,同时要保证S3的权限配置正确。

性能优化建议

  • 尽量拆分更长的固定前缀传给S3的list API,减少拉取的对象数量
  • 如果文件量超过10万,建议开启S3清单功能,定期导出全量对象列表做查询,比每次实时list性能高很多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 05:06:03