.net core AWS S3文件存储桶操作
.net core AWS S3文件存储桶操作
S3存储桶操作有几种场景,
这里就只讲两种
一种是在EC2服务器上,使用 IAM 角色直接操作的
一种是通过账号密码,请求操作
其中S3文件有加密操作,可根据自己的需求而定
一. 在EC2服务器上,使用 IAM
角色直接操作
这种情况是最简单的
由于在写程序的过程中,如果不是自己的S3存储桶,不能登录查看,
没办法直接看到存储桶内,文件上传下载情况,不好测试,这里教大家一个简单点的方法,直接使用cmd命令,查看情况。
CMD命令操作示例如下:
以下命令直接输入:
// 读取EC2服务器默认S3配置
aws configure
// 查看存储同或文件情况情况:
aws s3 ls s3://***/
// *** 这里直接写存储桶名称即可,也可以直接写到指定文件夹
// 上传单个文件
aws s3 cp C:/Users/test.txt s3://***/test/
// 如果没有S3没有test文件夹,会自动创建
// 下载文件,反过来写即可
aws s3 cp C:/Users/ s3://***/test/test.txt
// 删除文件
aws s3 rm s3://xxx/test/ --recursive
有了这些命令之后,在调成程序的过程中,我们就能更好的查看文件的操作效果了,接下来,正式进入AWS S3 ,.NET Core的程序编写
1.首先我们需要用NuGet安装一些拓展
AWSSDK.S3
AWSSDK.Extensions.NETCore.Setup
后面直接上代码:
Startup.cs文件配置,添加如下代码,其余自行填充:
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public void ConfigureServices(IServiceCollection services)
{
IAmazonS3 client = Configuration.GetAWSOptions().CreateServiceClient<IAmazonS3>();
// 存储桶名称 如:s3://***/,直接填写***
AwsStorageClient.BucketName = "***";
AwsStorageClient.Storage = new AwsStorageHelper(client);
services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
services.AddAWSService<IAmazonS3>();
services.AddOptions();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var options = Configuration.GetAWSOptions();
IAmazonS3 client = options.CreateServiceClient<IAmazonS3>();
}
AwsStorageHelper.cs 文件内容:
public class AwsStorageHelper
{
IAmazonS3 S3Client { get; set; }
public static string BaseURL { get; set; }
public AwsStorageHelper(IAmazonS3 s3Client)
{
S3Client = s3Client;
}
/// <summary>
/// Get S3 Client for connecting to S3
/// </summary>
/// <returns>S3 Client</returns>
public IAmazonS3 GetClient()
{
if (S3Client != null)
{
return S3Client;
}
//为了确保不出意外,防止为null,重新实例化
var config = new AmazonS3Config { ServiceURL = BaseURL };
return S3Client = new AmazonS3Client(config);
}
}
AwsStorageClient.cs 文件操作底层封装方法,简单的上传,下载,删除:
public class AwsStorageClient
{ /// <summary>
/// Storage Helper - this is injected by Windsor. Provides the S3 client.
/// </summary>
public static AwsStorageHelper Storage { get; set; }
/// <summary>
/// Bucket Name - this must be set before use.
/// </summary>
public static string BucketName { get; set; }
/// <summary>
/// 验证文件是否存在
/// </summary>
/// <param name="filePath"></param>
/// <returns></returns>
public bool Exists(string filePath)
{
EnsureBucketName();
filePath = CleanFilePath(filePath);
var client = Storage.GetClient();
ListObjectsV2Request request = new ListObjectsV2Request
{
BucketName = BucketName,
};
//var s3DirectoryInfo = new S3DirectoryInfo(client, BucketName);
ListObjectsV2Response response = client.ListObjectsV2Async(request).Result;
return response.S3Objects.Exists(c => c.Key == filePath);
}
public void WriteFile(string filePath, Stream fileContent)
{
EnsureBucketName();
filePath = CleanFilePath(filePath);
var client = Storage.GetClient();
using (var uploader = new TransferUtility(client))
{
uploader.Upload(fileContent, BucketName, filePath);
}
}
public long FileSize(string filePath)
{
EnsureBucketName();
filePath = CleanFilePath(filePath);
var client = Storage.GetClient();
using (var response = client.ListObjectsAsync(new ListObjectsRequest { BucketName = BucketName, Prefix = filePath }))
{
if (response.Result.S3Objects.Count > 0)
{
return response.Result.S3Objects.First().Size;
}
return 0;
}
}
public string FileType(string filePath)
{
return "application/octet-stream";
}
/// <summary>
/// 上传文件
/// </summary>
/// <param name="base64Key"></param>
/// <param name="filePath"></param>
/// <returns></returns>
public async Task<PutObjectRequest> UploadObjectAsync(string base64Key, string filePath)
{
var client = Storage.GetClient();
PutObjectRequest putObjectRequest = new PutObjectRequest
{
BucketName = BucketName,
Key = filePath,
ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,// 文件加密,可不要
ServerSideEncryptionCustomerProvidedKey = base64Key,// 文件加密,可不要
};
PutObjectResponse putObjectResponse = await client.PutObjectAsync(putObjectRequest);
return putObjectRequest;
}
/// <summary>
/// 读取文件
/// </summary>
/// <param name="filePath"></param>
/// <param name="base64Key"></param>
/// <returns></returns>
public Stream ReadFile(string filePath,string base64Key)
{
EnsureBucketName();
filePath = CleanFilePath(filePath);
var client = Storage.GetClient();
GetObjectRequest request = new GetObjectRequest()
{
BucketName = BucketName,
Key = filePath,
ServerSideEncryptionCustomerMethod = ServerSideEncryptionCustomerMethod.AES256,// 文件加密,可不要
ServerSideEncryptionCustomerProvidedKey = base64Key// 文件加密,可不要
};
var response = client.GetObjectAsync(request);
return response.Result.ResponseStream;
}
private void EnsureBucketName()
{
if (BucketName == string.Empty)
{
throw new Exception("Bucket Name must be set before using the S3 storage client");
}
}
private string CleanFilePath(string path)
{
// remove leading slashes
if (path.Length > 0 && path.Substring(0, 1) == "/")
{
path = Regex.Replace(path, "^[/]+(.*)$", "$1");
}
return path;
}
public class S3Response
{
public HttpStatusCode Status { get; set; }
public string Message { get; set; }
}
/// <summary>
/// 删除一个对象
/// </summary>
/// <param name="key">删除的对象的键如:resource/img/basketballnews/test1.jpg</param>
/// <returns></returns>
public async Task<bool> DeleteAnObjectAsync(string keyName)
{
try
{
// 1. Delete object-specify only key name for the object.
var deleteRequest1 = new DeleteObjectRequest
{
BucketName = BucketName,
Key = keyName
};
var client = Storage.GetClient();
DeleteObjectResponse response1 = await client.DeleteObjectAsync(deleteRequest1);
return true;
}
catch (AmazonS3Exception e)
{
throw new Exception(string.Format("Error encountered ***. Message:'{0}' when writing an object", e.Message));
}
catch (Exception e)
{
throw new Exception(string.Format("Unknown encountered on server. Message:'{0}' when writing an object", e.Message));
}
}
}
最后就是控制器层的调用了,AWSController.cs
[Produces("application/json")]
[Consumes("application/json", "multipart/form-data")]//此处为新增
[Route("api/[controller]/[action]")]
public class AWSController : Controller
{
IAmazonS3 S3Client { get; set; }
public AWSController(IAmazonS3 s3Client)
{
this.S3Client = s3Client;
}
/// <summary>
/// S3 存储桶 异步删除文件
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<IActionResult> DeleteFilesS3Async()
{
AwsStorageClient aws = new AwsStorageClient();
string awsfilePath = "s3Test/text/text.txt";
await aws.DeleteAnObjectAsync(awsfilePath);
return Ok();
}
/// <summary>
/// S3 存储桶 上传文件
/// </summary>
/// <returns></returns>
[HttpPost]
[DisableRequestSizeLimit]
public async Task<ActionResult<bool>> UploadFileS3(IFormFile file)
{
string awsfilePath = "s3Test/test/" + file.FileName;// 上传 AWS 文件路径,文件名全路径,带后缀
AwsStorageClient aws = new AwsStorageClient();
string base64Key = "none";
// 文件是否需要加密根据自己情况而定
Aes aesEncryption = Aes.Create();
aesEncryption.KeySize = 256;
aesEncryption.GenerateKey();
base64Key = Convert.ToBase64String(aesEncryption.Key);
await aws.UploadObjectAsync(base64Key, awsfilePath);
return ActionResultUtil.JsonText(base64Key);
}
/// <summary>
/// S3 存储桶 下载文件
/// </summary>
/// <returns></returns>
[HttpPost]
public ActionResult<Stream> DownFileS3([FromBody]string base64Key, string filePath)
{
AwsStorageClient aws = new AwsStorageClient();
// filePath = "s3Test/test/001.png";
bool res = aws.Exists(filePath);
try
{
if (res)
return aws.ReadFile(filePath, base64Key);
else
return NotFound();
}
catch (Exception)
{
return NotFound();
}
}
}
以上就是第一种的操作解决方案,相比第二种,它没什么重要配置。
而第二种需要配置一些相关信息,通过账号,密码去访问
二. 通过AccessKey
,SecretKey
登录操作
底层操作基本一致,只需要配置好相关的key就行,
我这里就直接在Startup.cs中进行登录,
其他代码,基本与方案一一致,可直接使用方案一代码程序。
public Startup(IConfiguration configuration, IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public void ConfigureServices(IServiceCollection services)
{
IAmazonS3 client = Configuration.GetAWSOptions().CreateServiceClient<IAmazonS3>();
// 存储桶名称 如:s3://***/,直接填写***
AwsStorageClient.BucketName = "***";
AwsStorageHelper.BaseURL = Configuration["AWS:BaseURL"]; // s3服务器地址,一般都直接使用的“s3.amazonaws.com” ,不配置也没什么问题
AmazonS3Config config = new AmazonS3Config()
{
ServiceURL = AwsStorageHelper.BaseURL,
RegionEndpoint = RegionEndpoint.APNortheast1,
};
AwsStorageClient.Storage =
new AwsStorageHelper(
new AmazonS3Client(Configuration["AWS:AccessKey"], Configuration["AWS:SecretKey"], config));
AwsStorageClient.Storage = new AwsStorageHelper();
services.AddDefaultAWSOptions(Configuration.GetAWSOptions());
services.AddAWSService<IAmazonS3>();
services.AddOptions();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var options = Configuration.GetAWSOptions();
IAmazonS3 client = options.CreateServiceClient<IAmazonS3>();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!