使用 AWS SDK for C++ 在 C++ 中操作 S3 和云存储
在现代应用程序开发中,与云存储的集成需求日益增加。Amazon S3(简单存储服务)是云中对象存储的事实标准。对于 C++ 语言,最强大且受支持的解决方案是官方库 AWS SDK for C++ (aws-sdk-cpp)。它不仅提供了与 S3 配合使用的完整工具集,还支持 MinIO、DigitalOcean Spaces、Yandex Object Storage 以及任何其他兼容 S3 的存储。
特性与优势
- 完整的 API — 该库涵盖了所有 S3 操作:创建/删除存储桶、上传/下载对象、版本管理、大文件的多线程上传。
- 跨平台 — 可在 Linux、macOS、Windows 以及移动平台(iOS、Android)上运行。
- 异步支持 — 通过 futures 内置支持 async/await,允许编写高效的非阻塞代码。
- 与 S3 替代方案兼容 — 只需更改 endpoint 和 credentials,即可从 AWS S3 切换到 MinIO 或 Yandex Object Storage。
- 流式支持 — 通过
std::iostream直接上传/下载数据,无需将整个文件保存在内存中。
安装与配置
该库可通过 vcpkg、Conan 分发,或从源码编译。推荐方式是通过 vcpkg:
# 安装 vcpkg(如果尚未安装)git clone https://github.com/Microsoft/vcpkg.gitcd vcpkg./bootstrap-vcpkg.sh # 或 Windows 下使用 bootstrap-vcpkg.bat
# 安装 S3 的 SDK./vcpkg install aws-sdk-cpp[s3]在 CMakeLists.txt 中添加:
find_package(AWSSDK REQUIRED COMPONENTS s3)target_link_libraries(your_target PRIVATE ${AWSSDK_LINK_LIBRARIES})基本示例:上传对象到 S3
开始之前,需要配置凭证。最安全的方式是使用 ~/.aws/credentials 文件或环境变量 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY。
#include <aws/core/Aws.h>#include <aws/s3/S3Client.h>#include <aws/s3/model/PutObjectRequest.h>#include <fstream>
int main() { Aws::SDKOptions options; Aws::InitAPI(options); { Aws::S3::S3Client s3_client;
const Aws::String bucket_name = "my-bucket"; const Aws::String object_key = "example.txt";
// 准备请求 Aws::S3::Model::PutObjectRequest request; request.SetBucket(bucket_name); request.SetKey(object_key);
// 读取文件 auto input_data = Aws::MakeShared<Aws::FStream>("tag", "local_file.txt", std::ios::in | std::ios::binary); request.SetBody(input_data);
// 执行请求 auto outcome = s3_client.PutObject(request); if (outcome.IsSuccess()) { std::cout << "文件上传成功!" << std::endl; } else { std::cerr << "错误:" << outcome.GetError().GetMessage() << std::endl; return 1; } } Aws::ShutdownAPI(options); return 0;}使用 MinIO(本地 S3 存储)
为了开发和测试,使用 MinIO 非常方便。要使 SDK 与 MinIO 配合使用,需要更改 endpoint 并禁用 SSL 验证(如果未配置 HTTPS):
#include <aws/core/Aws.h>#include <aws/s3/S3Client.h>
int main() { Aws::SDKOptions options; Aws::InitAPI(options); { // 为 MinIO 配置客户端 Aws::Client::ClientConfigura