Работа с S3 и облачными хранилищами в C# (.NET): AWS SDK и MinIO

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в S3 и облачные хранилища для .NET-разработчика

Облачные объектные хранилища, совместимые с протоколом Amazon S3 (Simple Storage Service), стали стандартом де-факто для хранения неструктурированных данных: изображений, видео, бэкапов, логов и артефактов сборки. В экосистеме C# (.NET) работа с такими хранилищами реализуется через официальный AWS SDK для .NET или через легковесные клиенты для S3-совместимых решений (MinIO, Yandex Object Storage, DigitalOcean Spaces).

В этой статье мы разберём основные операции: подключение, создание бакета, загрузку, скачивание и удаление объектов. Все примеры написаны на C# с использованием .NET 8.

Установка библиотеки AWS SDK для .NET

Для работы с S3 из C# необходимо установить NuGet-пакет AWS SDK for .NET — S3:

dotnet add package AWSSDK.S3
dotnet add package AWSSDK.Extensions.NETCore.Setup  // для DI-интеграции

Если вы используете MinIO или другие S3-совместимые хранилища (не AWS), достаточно того же пакета — он поддерживает кастомные endpoint'ы.

Базовая настройка S3-клиента

Создадим клиент для работы с S3. В примере ниже используется MinIO, запущенный локально на порту 9000:

using Amazon;
using Amazon.S3;
using Amazon.Runtime;

var config = new AmazonS3Config
{
    ServiceURL = "http://localhost:9000",  // для MinIO или другого S3-совместимого хранилища
    ForcePathStyle = true,                 // обязательно для MinIO
    UseHttp = true
};

var credentials = new BasicAWSCredentials("minioadmin", "minioadmin");
var s3Client = new AmazonS3Client(credentials, config);

Для AWS S3 достаточно указать регион и использовать стандартные credentials:

var s3Client = new AmazonS3Client(RegionEndpoint.EUWest1);

Создание и удаление бакета (bucket)

Создание бакета

public async Task CreateBucketAsync(string bucketName)
{
    var putBucketRequest = new PutBucketRequest
    {
        BucketName = bucketName,
        UseClientRegion = true
    };
    var response = await s3Client.PutBucketAsync(putBucketRequest);
    Console.WriteLine($"Бакет {bucketName} создан. HTTP статус: {response.HttpStatusCode}");
}

Проверка существования бакета

public async Task<bool> DoesBucketExistAsync(string bucketName)
{
    return await AmazonS3Util.DoesS3BucketExistAsync(s3Client, bucketName);
}

Удаление бакета

public async Task DeleteBucketAsync(string bucketName)
{
    await s3Client.DeleteBucketAsync(bucketName);
    Console.WriteLine($"Бакет {bucketName} удалён.");
}

Загрузка файлов (Upload)

Самый распространённый сценарий — загрузка файла в бакет. Используем PutObjectAsync:

public async Task UploadFileAsync(string bucketName, string key, string filePath)
{
    var putRequest = new PutObjectRequest
    {
        BucketName = bucketName,
        Key = key,
        FilePath = filePath,
        ContentType = "application/octet-stream"
    };

    var response = await s3Client.PutObjectAsync(putRequest);
    Console.WriteLine($"Файл {key} загружен. ETag: {response.ETag}");
}

Загрузка из потока (stream) — полезно для файлов, полученных от пользователя через веб-форму:

public async Task UploadFromStreamAsync(string bucketName, string key, Stream inputStream)
{
    var putRequest = new PutObjectRequest
    {
        BucketName = bucketName,
        Key = key,
        InputStream = inputStream
    };
    await s3Client.PutObjectAsync(putRequest);
}

Скачивание файлов (Download)

Скачать объект можно в файл или в поток:

public async Task DownloadFileAsync(string bucketName, string key, string downloadPath)
{
    var getRequest = new GetObjectRequest
    {
        BucketName = bucketName,
        Key = key
    };

    using var response = await s3Client.GetObjectAsync(getRequest);
    await response.WriteResponseStreamToFileAsync(downloadPath, false, CancellationToken.None);
    Console.WriteLine($"Файл {key} скачан в {downloadPath}");
}

Получение объекта в виде потока для дальнейшей обработки:

public async Task<Stream> GetObjectStreamAsync(string bucketName, string key)
{
    var getRequest = new GetObjectRequest
    {
        BucketName = bucketName,
        Key = key
    };
    var response = await s3Client.GetObjectAsync(getRequest);
    return response.ResponseStream;
}

Рекомендаций