candy-s3:一个让你少操心的对象存储封装库
大家好!今天想和大家聊聊 candy-s3 —— 一个轻量、可靠、专为“省事”而生的跨云对象存储封装库。如果你曾经被多云对象存储的 SDK 折磨过,或者只是想快速搞定上传下载,又不想被一堆配置和依赖拖慢节奏,那它可能正是你一直在找的工具。
为什么会有 candy-s3?
当今开发中,对象存储早已不是“选不选”的问题,而是“怎么用得更顺手”。但现实往往很骨感:
- 多厂商 SDK 集成太重:AWS S3、阿里云 OSS、腾讯云 COS……虽然每个都声称是AWS S3 compatible,但是每个都有自己的 SDK,项目一支持多云,依赖就爆炸,引入了一堆SDK却只用到了GetObject/PutObject。
- 原生 S3 SDK 学习成本高:哪怕只是上传个文件,也得搞懂 credential chain、region、builder 嵌套、异常分类……
- 自己封装又怕翻车:不同厂商的 S3 兼容接口总有细微差异(比如分片大小限制、分页行为),没做足测试,线上就容易出问题;接口设计不好,后续迭代更是灾难。
能不能一套代码、兼容多云呢?在github搜了半天,居然真没有合适的项目。
于是,我们做了 candy-s3 —— 一个基于 Java 的轻量级封装库,直接对接AWS S3 API,根据AWS S3标准定义接口规范,之后不管你用r2,oss,cos,obs,minio,只要是AWS S3 Compatible,就都通用!目标很简单:让你用最熟悉的 S3 操作方式,一次写代码,到处跑服务。
它能为你解决什么?
原生 S3 接口对齐,零额外学习成本
candy-s3 的 API 设计完全遵循 S3 的操作语义。你会用 putObject、getObject、listObjects,就能立刻上手,不需要学任何新概念。更重要的是,它内部已经帮你屏蔽了不同厂商 S3 兼容服务的差异,真正做到“一次编码,多云适配”。
多云无缝兼容,切换后端只需改配置
无论是:
- AWS S3
- 阿里云 OSS
- 腾讯云 COS
- Cloudfalre R2
- MinIO(私有化部署)
- 其他对象存储服务...(obs,qiniu,others...)
只要支持标准 S3 协议,candy-s3 就能直接对接,不用引入每个云厂商的一堆存储、认证、签名sdk。换存储后端,不用动业务代码,只改 endpoint 和密钥就行。
完备单元测试,可靠性有保障,单元测试即文档
一个开源工具要进生产环境,稳定比功能更重要,文档比代码更重要,而最好的文档就是代码。在这个项目上投入的80%以上时间,都用在了编写单元测试——引入后你甚至不需要手写代码,copy单元测试就覆盖了你能用到的所有对象存储场景。不仅覆盖了 Put、Get、List、MultipartUpload分片上传 等核心操作,还包含了Versioning版本控制、Condition Write条件写入、ObjectLock对象锁、LegalHold合法保留、SSE服务端加密等高级特性,异常情况、边界条件都有验证。
接口稳定 + 依赖精简,长期维护无压力
- 接口定义文档,保持向后兼容,绝不轻易 break your code。
- 仅依赖 Jackson 和 OkHttp 这两个成熟、轻量的第三方库(我相信你代码本身就依赖了他们),没有冗余依赖,减少冲突风险。
- 遵循“接口不变,实现可扩展”的原则,未来新增功能也不会影响现有调用。
开发者有意在新版本中将OkHttp也移除,直接使用java内置http库,进一步精简依赖
来看看实际怎么用?
单元测试就是最好的文档,引入后你甚至不需要手写代码,copy单元测试就覆盖了你能用到的所有对象存储场景
1. 引入依赖(Maven)
<dependency>
<groupId>io.github.matian2014</groupId>
<artifactId>candy-s3</artifactId>
<version>1.0.0</version>
</dependency>
2. 初始化客户端
// Create AWS S3 client
CandyS3 client = new CandyS3(S3Provider.AWS);
client.setAccessKey("your-access-key");
client.setSecretKey("your-secret-key");
client.setRegion("us-east-1");
3. 上传文件(Put)
// Upload object
String content = "Hello, World!";
PutObjectOptions putOptions = new PutObjectOptions.PutObjectOptionsBuilder()
.configureUploadData().withData(content.getBytes()).endConfigureDataContent()
.build();
String etag = client.putObject("my-bucket", "my-object", putOptions);
candy-s3d的putObject()方法支持对大对象自动化分片上传
4. 下载文件(Get)
// Download object
DownloadObjectOptions downloadOptions = new DownloadObjectOptions.DownloadObjectOptionsBuilder()
.configureDataOutput().toBytes().endConfigureDataOutput()
.build();
S3Object object = client.getObject("my-bucket", "my-object", downloadOptions);
5. 手动分片上传(Multipart Upload)
String objectKey = "multipartUploadObject.data";
String uploadId = candyS3.createMultipartUpload(bucket, objectKey,
new CreateMultipartUploadOptions.CreateMultipartUploadOptionsBuilder().build());
List<S3Part> parts = new ArrayList<>();
S3Part part11 = candyS3.uploadPart(bucket, objectKey, uploadId, 1,
new UploadPartOptions.UploadPartOptionsBuilder()
.configureUploadData()
.withData(Arrays.copyOfRange(bytes, 0, 5 * 1024 * 1024))
.endConfigureDataContent()
.build());
parts.add(part11);
S3Part part12 = candyS3.uploadPart(bucket, objectKey, uploadId, 2,
new UploadPartOptions.UploadPartOptionsBuilder()
.configureUploadData()
.withData(Arrays.copyOfRange(bytes, 5 * 1024 * 1024, bytes.length))
.endConfigureDataContent()
.build());
parts.add(part12);
candyS3.completeMultipartUpload(bucket, objectKey, uploadId, parts,
new CompleteMultipartUploadOptions.CompleteMultipartUploadOptionsBuilder().build());
适合哪些场景?
- 中小型项目:不想引入重型 SDK,只想快速实现文件上传下载。
- 多云/混合云架构:需要灵活切换存储后端,但不想每次重写适配层。
- MinIO 私有化部署:希望有一套标准、可靠的 Java 客户端统一管理。
- 快速原型验证:今天有个想法,明天就想跑通存储逻辑?candy-s3 能帮你省下大半天。
- 云服务功能完备性验证:不确定迁移对象存储服务商后功能完备性,candy-s3跑一轮单元测试一目了然
生产环境怎么用得更好?
虽然 candy-s3 已经足够稳定,但在生产中还是建议注意几点:
- 配置优化:根据网络环境设置合理的连接/读取超时。
- 异常处理 + 重试:建议封装通用异常处理逻辑,并对网络波动类错误(如
SocketTimeoutException)引入重试机制(例如用 Guava Retrying)。 - 权限最小化:访问密钥务必遵循“最小权限原则”,避免泄露;公开对象可通过 ACL 控制,无需在代码里硬编码权限逻辑。
未来计划 & 欢迎共建!
目前 candy-s3 1.0.0 已覆盖日常 90%+ 的使用场景,并将长期持续维护。
非常欢迎你来参与! 欢迎Issue,欢迎PR,更期待你的Star!
项目采用标准 Git Flow 工作流,代码清晰,测试完备,新手也能快速上手。
GitHub 地址:github.com/matian2014/…
Gitee 地址:gitee.com/connormma/c…