.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();
            }
        }
    }

以上就是第一种的操作解决方案,相比第二种,它没什么重要配置。
而第二种需要配置一些相关信息,通过账号,密码去访问

二. 通过AccessKeySecretKey登录操作

底层操作基本一致,只需要配置好相关的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>();
    }
欢迎扫码关注,加好友

加好友

# .net core   AWS   S3  

评论

友情链接:

陌上花开

神奇的海螺

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×