Библиотека aws-sdk-cpp: интеграция S3 и облачных хранилищ в C++
Современные C++ приложения всё чаще требуют взаимодействия с облачными хранилищами. Будь то резервное копирование, хранение медиафайлов или обмен данными между сервисами — S3-совместимые хранилища (Amazon S3, MinIO, Yandex Object Storage, DigitalOcean Spaces) стали стандартом де-факто. Официальная библиотека aws-sdk-cpp от Amazon предоставляет мощный и гибкий инструментарий для работы с S3 напрямую из C++ кода.
В этой статье мы разберём, как подключить aws-sdk-cpp, настроить аутентификацию, выполнить базовые операции с объектами и бакетами, а также рассмотрим особенности работы с совместимыми хранилищами.
Что такое aws-sdk-cpp?
aws-sdk-cpp — это официальный SDK от Amazon Web Services для языка C++. Он включает модули для всех основных сервисов AWS, включая S3, DynamoDB, Lambda, EC2 и другие. Для работы с облачными хранилищами используется модуль S3, который поддерживает:
- Создание, удаление и перечисление бакетов (buckets).
- Загрузку, скачивание, копирование и удаление объектов.
- Работу с многокомпонентной загрузкой (multipart upload) для больших файлов.
- Управление метаданными и ACL (Access Control Lists).
- Поддержку потоковой передачи данных и асинхронных операций.
Установка и подключение
Самый простой способ установить SDK — через менеджер пакетов vcpkg:
vcpkg install aws-sdk-cpp[s3]
Для ручной сборки из исходников потребуется CMake и компилятор с поддержкой C++14 или новее. После установки подключаем библиотеку в CMakeLists.txt:
find_package(aws-sdk-cpp REQUIRED COMPONENTS s3 s3-crt)
target_link_libraries(your_project PRIVATE AWS::aws-cpp-sdk-s3 AWS::aws-cpp-sdk-s3-crt)
Обратите внимание: s3-crt — это альтернативная реализация на основе Common Runtime, которая даёт лучшую производительность для потоковых операций.
Настройка клиента S3
Перед началом работы необходимо создать объект Aws::S3::S3Client. Для доступа к совместимым хранилищам (например, MinIO или Yandex Object Storage) нужно указать кастомный endpoint:
#include <aws/core/Aws.h>
#include <aws/s3/S3Client.h>
#include <aws/s3/model/ListObjectsV2Request.h>
Aws::SDKOptions options;
Aws::InitAPI(options);
{
Aws::Client::ClientConfiguration config;
config.endpointOverride = "https://storage.yandexcloud.net"; // для Yandex Object Storage
config.region = "ru-central1";
config.scheme = Aws::Http::Scheme::HTTPS;
// Для MinIO локально: config.endpointOverride = "http://localhost:9000";
// config.region = "us-east-1"; // MinIO по умолчанию использует эту регион
Aws::Auth::AWSCredentials credentials("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");
Aws::S3::S3Client s3_client(credentials, config);
// Далее работаем с клиентом
}
Aws::ShutdownAPI(options);
Пример: загрузка файла в S3
Рассмотрим базовую операцию — загрузку локального файла в бакет:
#include <aws/s3/model/PutObjectRequest.h>
#include <fstream>
bool UploadFile(const Aws::S3::S3Client& client,
const std::string& bucket_name,
const std::string& object_key,
const std::string& file_path)
{
Aws::S3::Model::PutObjectRequest request;
request.SetBucket(bucket_name);
request.SetKey(object_key);
std::shared_ptr<Aws::IOStream> input_data =
Aws::MakeShared<Aws::FStream>("UploadFile",
file_path.c_str(),
std::ios_base::in | std::ios_base::binary);
if (!input_data->good())
{
std::cerr << "Error opening file: " << file_path << std::endl;
return false;
}
request.SetBody(input_data);
auto outcome = client.PutObject(request);
if (outcome.IsSuccess())
{
std::cout << "File uploaded successfully. ETag: "
<< outcome.GetResult().GetETag() << std::endl;
return true