Работа с S3 и облачными хранилищами в C++ с помощью AWS SDK для C++
В современной разработке приложений всё чаще требуется интеграция с облачными хранилищами. Amazon S3 (Simple Storage Service) является де-факто стандартом для хранения объектов в облаке. Для языка C++ наиболее мощным и поддерживаемым решением является официальная библиотека AWS SDK для C++ (aws-sdk-cpp). Она предоставляет полный набор инструментов для работы не только с S3, но и с MinIO, DigitalOcean Spaces, Yandex Object Storage и любыми другими S3-совместимыми хранилищами.
Особенности и преимущества
- Полнота API — библиотека покрывает все операции S3: создание/удаление бакетов, загрузку/скачивание объектов, управление версиями, многопоточную загрузку больших файлов.
- Кроссплатформенность — работает на Linux, macOS, Windows, а также на мобильных платформах (iOS, Android).
- Асинхронность — встроенная поддержка async/await через futures, что позволяет писать эффективный неблокирующий код.
- Совместимость с S3-альтернативами — достаточно изменить endpoint и credentials, чтобы переключиться с AWS S3 на MinIO или Yandex Object Storage.
- Поддержка потоков — загрузка/скачивание данных напрямую через
std::iostreamбез сохранения в памяти всего файла.
Установка и подключение
Библиотека распространяется через vcpkg, Conan или собирается из исходников. Рекомендуемый способ — через vcpkg:
# Установка vcpkg (если ещё не установлен)
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh # или bootstrap-vcpkg.bat для Windows
# Установка SDK для S3
./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::ClientConfiguration config;
config.endpointOverride = "http://localhost:9000"; // адрес MinIO
config.scheme = Aws::Http::Scheme::HTTP; // без HTTPS
config.verifySSL = false;
Aws::S3::S3Client s3_client(config);
// Дальше код такой же, как и для AWS S3
Aws::S3::Model::ListBucketsOutcome outcome = s3_client.ListBuckets();
if (outcome.IsSuccess()) {
for (const auto& bucket : outcome.GetResult().GetBuckets()) {
std::cout <<