Introdução ao S3 e armazenamentos em nuvem para desenvolvedores .NET
Os armazenamentos de objetos em nuvem compatíveis com o protocolo Amazon S3 (Simple Storage Service) tornaram-se o padrão de facto para armazenar dados não estruturados: imagens, vídeos, backups, logs e artefatos de build. No ecossistema C# (.NET), o trabalho com esses armazenamentos é implementado através do oficial AWS SDK para .NET ou através de clientes leves para soluções compatíveis com S3 (MinIO, Yandex Object Storage, DigitalOcean Spaces).
Neste artigo, abordaremos as operações principais: conexão, criação de bucket, upload, download e exclusão de objetos. Todos os exemplos são escritos em C# usando .NET 8.
Instalação da biblioteca AWS SDK para .NET
Para trabalhar com S3 a partir do C#, é necessário instalar o pacote NuGet AWS SDK for .NET — S3:
dotnet add package AWSSDK.S3dotnet add package AWSSDK.Extensions.NETCore.Setup // para integração DISe você estiver usando MinIO ou outros armazenamentos compatíveis com S3 (que não sejam AWS), o mesmo pacote é suficiente — ele suporta endpoints personalizados.
Configuração básica do cliente S3
Vamos criar um cliente para trabalhar com S3. No exemplo abaixo, é usado o MinIO, executado localmente na porta 9000:
using Amazon;using Amazon.S3;using Amazon.Runtime;
var config = new AmazonS3Config{ ServiceURL = "http://localhost:9000", // para MinIO ou outro armazenamento compatível com S3 ForcePathStyle = true, // obrigatório para MinIO UseHttp = true};
var credentials = new BasicAWSCredentials("minioadmin", "minioadmin");var s3Client = new AmazonS3Client(credentials, config);Para AWS S3, basta especificar a região e usar as credentials padrão:
var s3Client = new AmazonS3Client(RegionEndpoint.EUWest1);Criação e exclusão de bucket
Criação de bucket
public async Task CreateBucketAsync(string bucketName){ var putBucketRequest = new PutBucketRequest { BucketName = bucketName, UseClientRegion = true }; var response = await s3Client.PutBucketAsync(putBucketRequest); Console.WriteLine($"Bucket {bucketName} criado. Status HTTP: {response.HttpStatusCode}");}Verificação de existência do bucket
public async Task<bool> DoesBucketExistAsync(string bucketName){ return await AmazonS3Util.DoesS3BucketExistAsync(s3Client, bucketName);}Exclusão de bucket
public async Task DeleteBucketAsync(string bucketName){ await s3Client.DeleteBucketAsync(bucketName); Console.WriteLine($"Bucket {bucketName} excluído.");}Upload de arquivos
O cenário mais comum é o upload de um arquivo para um bucket. Usamos 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($"Arquivo {key} enviado. ETag: {response.ETag}");}Upload a partir de um stream — útil para arquivos recebidos do usuário através de um formulário web:
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 de arquivos
É possível baixar um objeto para um arquivo ou para um stream:
public async Task DownloadFileAsync(string bucketName, string key, string downloadPath){ Também na biblioteca
openapi-typescript para TypeScript: guia completo com exemplos
Trabalhando com S3 e armazenamentos em nuvem em Kotlin: AWS SDK e MinIO
Migrações de banco de dados em Java: visão geral de ferramentas e bibliotecas
TBB (Intel Threading Building Blocks) para C++: guia completo com exemplos