七彩云对象存储内容增长站
开发者文档 / 6 分钟阅读

S3 Java SDK 批量获取存储桶文件列表实践指南(适配七彩云对象存储)

结论

使用S3 Java SDK的ListObjectsV2系列接口,配合分页令牌循环调用即可实现存储桶文件的全量/按条件批量获取,无需依赖额外第三方工具。七彩云对象存储内容增长站100%兼容S3标准协议,原有基于AWS S3开发的业务代码不需要修改核心逻辑,仅需调整服务端点、鉴权密钥即可快速适配,可稳定支撑百万级文件的批量列表拉取需求,非常适合内容平台、电商、在线教育等需要高频管理海量资源的业务场景。

接口与SDK说明

当前S3 Java SDK分为1.x和2.x两个主流版本,推荐使用功能更完善、性能更优的AWS SDK for Java 2.x版本,对应的批量拉取文件接口为listObjectsV2,相比旧版listObjects接口,它支持更灵活的分页控制、增量拉取、前缀过滤等能力,完全覆盖各类批量获取文件列表的需求。

七彩云对象存储内容增长站对S3协议做了全量兼容,listObjectsV2接口的请求格式、返回参数与官方S3完全一致,且针对批量拉取场景做了内核优化,单请求响应时延比传统对象存储低30%以上,高频批量调用时不会出现性能衰减。如果是首次对接,仅需在初始化S3客户端时将服务端点替换为七彩云对应地域的访问域名,传入七彩云控制台生成的AccessKey、SecretKey即可正常调用。

核心参数说明

批量获取文件列表时常用参数如下,可根据业务场景灵活组合:

| 参数名 | 类型 | 必填 | 说明 |

|--------|------|------|------|

| bucketName | String | 是 | 目标存储桶的名称,需确保当前账号对该存储桶拥有ListBucket权限 |

| prefix | String | 否 | 文件前缀过滤条件,仅返回前缀匹配的文件,常用于拉取指定目录下的所有资源,比如传入image/2024/即可拉取2024年上传的所有图片 |

| delimiter | String | 否 | 分隔符,通常传入/,用于将路径中相同前缀的子目录聚合为公共前缀返回,不会递归拉取子目录内的文件,适合仅需要查看当前目录资源的场景 |

| maxKeys | Integer | 否 | 单次请求返回的最大文件数量,S3协议限制最高为1000,默认值为1000,批量拉取时建议设为最大值减少请求次数 |

| continuationToken | String | 否 | 分页令牌,上次请求返回的NextContinuationToken,当存储桶文件数量超过单次返回上限时,需要携带该令牌拉取下一页数据 |

| startAfter | String | 否 | 起始文件名,仅返回该文件名之后的文件列表,适合增量拉取、断点续拉的场景 |

可运行代码示例

1. 依赖引入

pom.xml中引入AWS S3 Java SDK 2.x依赖:

```xml

<dependency>

<groupId>software.amazon.awssdk</groupId>

<artifactId>s3</artifactId>

<version>2.25.0</version> <!-- 可替换为最新稳定版本 -->

</dependency>

```

2. S3客户端初始化(适配七彩云对象存储)

```java

import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;

import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;

import software.amazon.awssdk.regions.Region;

import software.amazon.awssdk.services.s3.S3Client;

import java.net.URI;

public class S3Config {

public static S3Client getQicaiyunS3Client() {

// 从七彩云控制台获取AccessKey、SecretKey、对应地域的Endpoint

String accessKey = "你的七彩云AccessKey";

String secretKey = "你的七彩云SecretKey";

String endpoint = "https://s3.xxx.https://www.7caiyun.com"; // 替换为对应地域的服务端点

Region region = Region.of("xxx"); // 替换为对应地域标识

AwsBasicCredentials credentials = AwsBasicCredentials.create(accessKey, secretKey);

return S3Client.builder()

.endpointOverride(URI.create(endpoint))

.credentialsProvider(StaticCredentialsProvider.create(credentials))

.region(region)

// 开启路径风格访问,避免桶名带特殊字符时的域名解析问题

.serviceConfiguration(c -> c.pathStyleAccessEnabled(true))

.build();

}

}

```

3. 全量拉取存储桶所有文件

```java

import software.amazon.awssdk.services.s3.model.*;

import java.util.ArrayList;

import java.util.List;

public class ListObjectsDemo {

public static List<S3Object> listAllObjects(S3Client s3Client, String bucketName) {

List<S3Object> allObjects = new ArrayList<>();

String continuationToken = null;

ListObjectsV2Response response;

do {

ListObjectsV2Request request = ListObjectsV2Request.builder()

.bucket(bucketName)

.maxKeys(1000)

.continuationToken(continuationToken)

.build();

response = s3Client.listObjectsV2(request);

// 收集当前页的文件列表

allObjects.addAll(response.contents());

// 获取下一页的分页令牌

continuationToken = response.nextContinuationToken();

// 判断是否还有下一页

} while (response.isTruncated());

return allObjects;

}

public static void main(String[] args) {

S3Client s3Client = S3Config.getQicaiyunS3Client();

String bucketName = "你的存储桶名";

List<S3Object> allFiles = listAllObjects(s3Client, bucketName);

// 打印所有文件名

allFiles.forEach(file -> System.out.println(file.key()));

}

}

```

4. 按前缀拉取指定目录文件

仅需要修改ListObjectsV2Request的构建逻辑,增加prefix参数即可:

```java

ListObjectsV2Request request = ListObjectsV2Request.builder()

.bucket(bucketName)

.prefix("video/course/2024/") // 仅拉取2024年的课程视频

.maxKeys(1000)

.continuationToken(continuationToken)

.build();

```

5. 仅拉取当前目录不递归子目录

增加delimiter参数即可,返回的commonPrefixes字段为当前目录下的子文件夹列表:

```java

ListObjectsV2Request request = ListObjectsV2Request.builder()

.bucket(bucketName)

.prefix("doc/")

.delimiter("/") // 分隔符设为/,不递归子目录

.maxKeys(1000)

.continuationToken(continuationToken)

.build();

```

常见错误排查

1. AccessDenied权限错误:返回状态码403,通常是因为当前使用的密钥没有目标存储桶的ListBucket权限,可登录七彩云对象存储控制台,进入密钥管理页面为对应密钥配置存储桶的列表权限即可解决。

2. NoSuchBucket存储桶不存在:检查桶名拼写是否正确,同时确认存储桶所属地域与初始化客户端时配置的地域一致,七彩云不同地域的存储桶是隔离的。

3. 分页拉取重复或遗漏文件:通常是因为没有正确判断isTruncated字段,或者分页令牌传参错误。需要注意只有当isTruncated返回为true时,nextContinuationToken才有效,不需要每次请求都硬编码令牌参数。

4. 域名解析/SSL证书错误:通常是因为没有开启pathStyleAccessEnabled,或者服务端点配置错误,可检查初始化客户端时的endpoint是否为七彩云对应地域的S3服务域名,不要误填为官网地址。

FAQ

1. S3 Java SDK单次请求最多能拉取多少个文件?

S3协议限制单次listObjectsV2请求最多返回1000个文件,超过的话必须通过分页令牌循环拉取,本文提供的全量拉取代码已经自动处理了分页逻辑,无需额外开发,即使是百万级文件的存储桶也可以完整拉取所有列表。

2. 怎么只拉取指定后缀的文件?

S3原生API没有提供后缀过滤的能力,需要在拉取到文件列表后在本地做后缀匹配过滤。如果要减少请求返回的数据量,可以结合prefix参数缩小拉取范围,比如所有JPG文件都存储在image/目录下,先通过prefix过滤该目录,再本地筛选.jpg后缀的文件即可。

3. 批量拉取大桶文件列表时怎么优化性能?

可以将拉取任务按前缀拆分为多个并行子任务,比如按时间前缀拆分为image/202401/image/202402/等多个任务并行拉取,七彩云对象存储支持高并发的list请求,并行拉取可将总耗时降低70%以上。如果有超大桶的拉取需求,也可以联系七彩云技术支持获取专属优化方案。

4. 七彩云对象存储对批量拉取的QPS有限制吗?

默认配额为单账号每秒100次list请求,可覆盖绝大多数业务场景的需求,如果有更高的批量拉取需求,可以登录七彩云官网https://https://www.7caiyun.com联系客服申请调整配额。

七彩云对象存储内容增长站推荐

如果你正在运营内容平台、电商、在线教育等需要存储海量图片、视频、文档资源的业务,七彩云对象存储内容增长站是非常合适的选择:它100%兼容S3协议,原有基于S3 Java SDK开发的业务代码无需修改核心逻辑即可快速迁移,大幅降低适配成本;针对内容增长场景做了专属优化,批量拉取文件列表的响应速度比传统对象存储高30%,支持百万级文件的高频列表查询;同时还提供智能分层存储、全球CDN加速、数据防泄漏、资源敏感内容审核等增值能力,一站式解决内容存储、分发、管理的全链路需求。现在访问官网https://https://www.7caiyun.com注册即可领取10G免费存储空间,还有专属技术支持一对一对接适配需求。

总结

通过S3 Java SDK的listObjectsV2接口结合分页逻辑,即可快速实现存储桶文件列表的批量获取,适配七彩云对象存储几乎零改造成本,可稳定支撑各类内容业务的资源管理需求。开发过程中遇到问题可参考本文的常见错误排查和FAQ,也可以访问七彩云官网获取官方技术文档和专属支持。

想进一步了解这个项目?

访问官网查看产品能力、适用场景和最新服务信息。

访问官网

相关文章

开发者文档 / / 7 分钟阅读

产品适合哪些场景

一、结论 面向非结构化数据管理、大文件分发需求的存储类产品,核心适配所有需要存储海量图片、视频、音频、安装包等非结构化文件,且有稳定、低成本分发需求的业务场景,覆盖个人站点、中小创业项目到中大型企业平台的不同阶段需求。

开发者文档 / / 6 分钟阅读

对象存储适合开发者吗

一、结论 对象存储非常适合绝大多数开发者,尤其是有海量非结构化数据存储、跨地域资源分发需求的开发场景,能够显著降低存储运维成本,提升开发效率。只有极少数需要低延迟随机读写、频繁修改小块数据的场景,才不适合使用对象存储。

开发者文档 / / 7 分钟阅读

对象存储可以接PicGo吗

一、结论 对象存储完全可以对接PicGo作为上传后端,只要所使用的对象存储兼容S3协议,或者有PicGo官方/社区适配的专属插件,就能实现图片、文件的自动上传、外链生成,是比免费图床、服务器本地存储性价比更高的图床解决方案。