隐藏

c#如何使用腾讯云COS实现对象存储

发布:2022/12/5 16:36:33作者:管理员 来源:本站 浏览次数:839

代码下载地址 https://github.com/whuanle/txypx20190809

前提


创建子账号


打开 https://console.cloud.tencent.com/cam


创建子用户,设置子账号策略为 AdministratorAccess ,或者参考https://cloud.tencent.com/document/product/436/11714 ,添加访问 COS 的权限 记录子用户的 账号ID。


切换子用户登录。


添加 appid 密钥


打开 https://console.cloud.tencent.com/cam/capi


新建 API 密钥,记录下 appid,记录 SecretId 和 SecretKey。


记录 Region


打开 https://cloud.tencent.com/document/product/436/6224


可以查询可用区/地域的 region。


本教程使用 C# 开发。

一,SDK 和使用


腾讯云官网提供了 .NET 版本的 对象存储(COS) SDK,并提供使用教程,教程链接:


https://cloud.tencent.com/document/product/436/32819


Nuget 搜索 Tencent.QCloud.Cos.Sdk 安装即可。


using 需引入


using COSXML;

using COSXML.Auth;

using COSXML.Model.Object;

using COSXML.Model.Bucket;

using COSXML.CosException;

using COSXML.Utils;

using COSXML.Model.Service;

using COSXML.Transfer;

using COSXML.Model;


根据官方的教程,很容易编写自己的软件:


Ctrl + C ,然后 Ctrl + V


拷贝完毕,大概是这样的


using System;

using System.Collections.Generic;

using System.Text;

using COSXML;

using COSXML.Auth;

using COSXML.Model.Object;

using COSXML.Model.Bucket;

using COSXML.CosException;

using COSXML.Utils;

using COSXML.Model.Service;

using COSXML.Transfer;

using COSXML.Model;


namespace CosTest

{

   public class CosClient

   {

       CosXmlServer cosXml;

       private readonly string _appid;

       private readonly string _region;

       public CosClient(string appid, string region)

       {

           _appid = appid;

           _region = region;


           //初始化 CosXmlConfig

           //string appid = "100011070645";

           //string region = "ap-guangzhou";

           CosXmlConfig config = new CosXmlConfig.Builder()

               .SetConnectionTimeoutMs(60000)

               .SetReadWriteTimeoutMs(40000)

               .IsHttps(true)

               .SetAppid(appid)

               .SetRegion(region)

               .SetDebugLog(true)

               .Build();


           QCloudCredentialProvider cosCredentialProvider = null;


           string secretId = "AKID62jALHsVmpfHentPs9E6lBMJ2XnnsTzH"; //"云 API 密钥 SecretId";

           string secretKey = "CC0c1DAtNdfS0IPIvISRFtIUSCUYTAgy"; //"云 API 密钥 SecretKey";

           long durationSecond = 600;  //secretKey 有效时长,单位为 秒

           cosCredentialProvider = new DefaultQCloudCredentialProvider(secretId, secretKey, durationSecond);


           //初始化 CosXmlServer

           cosXml = new CosXmlServer(config, cosCredentialProvider);

       }

       public bool CreateBucket(string buketName)

       {

           try

           {

               string bucket = buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID

               PutBucketRequest request = new PutBucketRequest(buketName);

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //执行请求

               PutBucketResult result = cosXml.PutBucket(request);

               //请求成功

               Console.WriteLine(result.GetResultInfo());

               return true;

           }

           catch (COSXML.CosException.CosClientException clientEx)

           {

               //请求失败

               Console.WriteLine("CosClientException: " + clientEx.Message);

               return false;

           }

           catch (COSXML.CosException.CosServerException serverEx)

           {

               //请求失败

               Console.WriteLine("CosServerException: " + serverEx.GetInfo());

               return false;

           }

       }

       public bool SelectBucket()

       {

           try

           {

               GetServiceRequest request = new GetServiceRequest();

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //执行请求

               GetServiceResult result = cosXml.GetService(request);

               //请求成功

               Console.WriteLine(result.GetResultInfo());

               return true;

           }

           catch (COSXML.CosException.CosClientException clientEx)

           {

               //请求失败

               Console.WriteLine("CosClientException: " + clientEx.Message);

               return false;

           }

           catch (COSXML.CosException.CosServerException serverEx)

           {

               //请求失败

               Console.WriteLine("CosServerException: " + serverEx.GetInfo());

               return false;

           }

       }


       public bool Upfile(string buketName, string key, string srcPath)

       {

           try

           {

               string bucket = buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID

               PutObjectRequest request = new PutObjectRequest(bucket, key, srcPath);

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //设置进度回调

               request.SetCosProgressCallback(delegate (long completed, long total)

               {

                   Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total));

               });

               //执行请求

               PutObjectResult result = cosXml.PutObject(request);

               //请求成功

               Console.WriteLine(result.GetResultInfo());

               return true;

           }

           catch (COSXML.CosException.CosClientException clientEx)

           {

               //请求失败

               Console.WriteLine("CosClientException: " + clientEx.Message);

               return false;

           }

           catch (COSXML.CosException.CosServerException serverEx)

           {

               //请求失败

               Console.WriteLine("CosServerException: " + serverEx.GetInfo());

               return false;

           }

       }

       public void UpBigFile(string buketName, string key, string srcPath)

       {

           string bucket = buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID


           TransferManager transferManager = new TransferManager(cosXml, new TransferConfig());

           COSXMLUploadTask uploadTask = new COSXMLUploadTask(bucket, null, key);

           uploadTask.SetSrcPath(srcPath);

           uploadTask.progressCallback = delegate (long completed, long total)

           {

               Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total));

           };

           uploadTask.successCallback = delegate (CosResult cosResult)

           {

               COSXML.Transfer.COSXMLUploadTask.UploadTaskResult result = cosResult as COSXML.Transfer.COSXMLUploadTask.UploadTaskResult;

               Console.WriteLine(result.GetResultInfo());

           };

           uploadTask.failCallback = delegate (CosClientException clientEx, CosServerException serverEx)

           {

               if (clientEx != null)

               {

                   Console.WriteLine("CosClientException: " + clientEx.Message);

               }

               if (serverEx != null)

               {

                   Console.WriteLine("CosServerException: " + serverEx.GetInfo());

               }

           };

           transferManager.Upload(uploadTask);

       }

       public class ResponseModel

       {

           public int Code { get; set; }

           public string Message { get; set; }

           public dynamic Data { get; set; }

       }

       public ResponseModel SelectObjectList(string buketName)

       {

           try

           {

               string bucket = buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID

               GetBucketRequest request = new GetBucketRequest(bucket);

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //执行请求

               GetBucketResult result = cosXml.GetBucket(request);

               //请求成功

               Console.WriteLine(result.GetResultInfo());

               return new ResponseModel { Code = 200, Data = result.GetResultInfo() };

           }

           catch (COSXML.CosException.CosClientException clientEx)

           {

               //请求失败

               Console.WriteLine("CosClientException: " + clientEx.Message);

               return new ResponseModel { Code = 200, Data = clientEx.Message };

           }

           catch (COSXML.CosException.CosServerException serverEx)

           {

               //请求失败

               Console.WriteLine("CosServerException: " + serverEx.GetInfo());

               return new ResponseModel { Code = 200, Data = serverEx.Message };

           }

       }

       public bool DownObject(string buketName, string key, string localDir, string localFileName)

       {

           try

           {

               string bucket = buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID

               GetObjectRequest request = new GetObjectRequest(bucket, key, localDir, localFileName);

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //设置进度回调

               request.SetCosProgressCallback(delegate (long completed, long total)

               {

                   Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total));

               });

               //执行请求

               GetObjectResult result = cosXml.GetObject(request);

               //请求成功

               Console.WriteLine(result.GetResultInfo());

               return true;

           }

           catch (COSXML.CosException.CosClientException clientEx)

           {

               //请求失败

               Console.WriteLine("CosClientException: " + clientEx.Message);

               return false;

           }

           catch (COSXML.CosException.CosServerException serverEx)

           {

               //请求失败

               Console.WriteLine("CosServerException: " + serverEx.GetInfo());

               return false;

           }

       }

       public bool DeleteObject(string buketName)

       {

           try

           {

               string bucket = buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID

               string key = "exampleobject"; //对象在存储桶中的位置,即称对象键.

               DeleteObjectRequest request = new DeleteObjectRequest(bucket, key);

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //执行请求

               DeleteObjectResult result = cosXml.DeleteObject(request);

               //请求成功

               Console.WriteLine(result.GetResultInfo());

               return true;

           }

           catch (COSXML.CosException.CosClientException clientEx)

           {

               //请求失败

               Console.WriteLine("CosClientException: " + clientEx.Message);

               return false;

           }

           catch (COSXML.CosException.CosServerException serverEx)

           {

               //请求失败

               Console.WriteLine("CosServerException: " + serverEx.GetInfo());

               return false;

           }

       }

   }

}



概览:


但是大神说,这样不好,程序要高内聚、低耦合,依赖与抽象而不依赖于具体实现。


那怎么办?只能修改一下。

二,优化

1,对象构建器


对象存储的 SDK 中,有三个重要的对象:


   CosXmlConfig 提供配置 SDK 接口。

   QCloudCredentialProvider 提供设置密钥信息接口。

   CosXmlServer 提供各种 COS API 服务接口。


但是,初始化和配置对象,过于麻烦,那么我们做一个对象构建器,实现函数式编程和链式语法。


   /// <summary>

   /// 生成Cos客户端工具类

   /// </summary>

   public class CosBuilder

   {

       private CosXmlServer cosXml;

       private string _appid;

       private string _region;

       private CosXmlConfig cosXmlConfig;

       private QCloudCredentialProvider cosCredentialProvider;

       public CosBuilder()

       {


       }



       public CosBuilder SetAccount(string appid, string region)

       {

           _appid = appid;

           _region = region;

           return this;

       }

       public CosBuilder SetCosXmlServer(int ConnectionTimeoutMs = 60000, int ReadWriteTimeoutMs = 40000, bool IsHttps = true, bool SetDebugLog = true)

       {

           cosXmlConfig = new CosXmlConfig.Builder()

               .SetConnectionTimeoutMs(ConnectionTimeoutMs)

               .SetReadWriteTimeoutMs(ReadWriteTimeoutMs)

               .IsHttps(true)

               .SetAppid(_appid)

               .SetRegion(_region)

               .SetDebugLog(true)

               .Build();

           return this;

       }

       public CosBuilder SetSecret(string secretId, string secretKey, long durationSecond = 600)

       {


           cosCredentialProvider = new DefaultQCloudCredentialProvider(secretId, secretKey, durationSecond);

           return this;

       }

       public CosXmlServer Builder()

       {

           //初始化 CosXmlServer

           cosXml = new CosXmlServer(cosXmlConfig, cosCredentialProvider);

           return cosXml;

       }

   }


2,消息响应对象


为了统一返回消息,创建一个 Response Model 的类。


   /// <summary>

   /// 消息响应

   /// </summary>

   public class ResponseModel

   {

       public int Code { get; set; }

       public string Message { get; set; }

       public dynamic Data { get; set; }

   }


3,接口


实际上,访问 COS和控制,和存储桶内的操作,是可以分开的。


访问 COS 可以控制对象存储内的所有东西,但是每个存储桶又是一个独立的对象。


为了松耦合,我们拆分两个客户端,一个用来管理连接、存储桶等,一个用来管理存储桶内的操作。


接口如下:



   public interface ICosClient

   {

       // 创建存储桶

       Task<ResponseModel> CreateBucket(string buketName);


       // 获取存储桶列表

       Task<ResponseModel> SelectBucket(int tokenTome = 600);

   }

   public interface IBucketClient

   {

       // 上传文件

       Task<ResponseModel> UpFile(string key, string srcPath);


       // 分块上传大文件

       Task<ResponseModel> UpBigFile(string key, string srcPath, Action<long, long> progressCallback, Action<CosResult> successCallback);


       // 查询存储桶的文件列表

       Task<ResponseModel> SelectObjectList();


       // 下载文件

       Task<ResponseModel> DownObject(string key, string localDir, string localFileName);


       // 删除文件

       Task<ResponseModel> DeleteObject(string buketName);

   }


所有接口功能都使用异步实现。

4,COS 客户端


基架代码:


   public class CosClient : ICosClient

   {

       CosXmlServer _cosXml;

       private readonly string _appid;

       private readonly string _region;

       public CosClient(CosXmlServer cosXml)

       {

           _cosXml = cosXml;

       }


   }


创建存储桶:



       public async Task<ResponseModel> CreateBucket(string buketName)

       {

           try

           {

               string bucket = buketName + "-" + _appid;

               PutBucketRequest request = new PutBucketRequest(bucket);

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //执行请求

               PutBucketResult result = await Task.FromResult(_cosXml.PutBucket(request));


               return new ResponseModel { Code = 200, Message = result.GetResultInfo() };

           }

           catch (COSXML.CosException.CosClientException clientEx)

           {

               //请求失败

               Console.WriteLine();

               return new ResponseModel { Code = 0, Message = "CosClientException: " + clientEx.Message };

           }

           catch (COSXML.CosException.CosServerException serverEx)

           {

               return new ResponseModel { Code = 200, Message = "CosServerException: " + serverEx.GetInfo() };

           }

       }


 


查询存储桶列表


       public async Task<ResponseModel> SelectBucket(int tokenTome = 600)

       {

           try

           {

               GetServiceRequest request = new GetServiceRequest();

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), tokenTome);

               //执行请求

               GetServiceResult result = await Task.FromResult(_cosXml.GetService(request));

               return new ResponseModel { Code = 200, Message = "Success", Data = result.GetResultInfo() };

           }

           catch (COSXML.CosException.CosClientException clientEx)

           {

               return new ResponseModel { Code = 0, Message = "CosClientException: " + clientEx.Message };

           }

           catch (CosServerException serverEx)

           {

               return new ResponseModel { Code = 0, Message = "CosServerException: " + serverEx.GetInfo() };

           }

       }


5,存储桶操作客户端


基架代码如下:


   /// <summary>

   /// 存储桶客户端

   /// </summary>

   public class BucketClient : IBucketClient

   {

       private readonly CosXmlServer _cosXml;

       private readonly string _buketName;

       private readonly string _appid;

       public BucketClient(CosXmlServer cosXml, string buketName, string appid)

       {

           _cosXml = cosXml;

           _buketName = buketName;

           _appid = appid;

       }


   }


上传对象


       public async Task<ResponseModel> UpFile(string key, string srcPath)

       {

           try

           {

               string bucket = _buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID

               PutObjectRequest request = new PutObjectRequest(bucket, key, srcPath);

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //设置进度回调

               request.SetCosProgressCallback(delegate (long completed, long total)

               {

                   Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total));

               });

               //执行请求

               PutObjectResult result = await Task.FromResult(_cosXml.PutObject(request));


               return new ResponseModel { Code = 200, Message = result.GetResultInfo() };

           }

           catch (CosClientException clientEx)

           {

               return new ResponseModel { Code = 0, Message = "CosClientException: " + clientEx.Message };

           }

           catch (CosServerException serverEx)

           {

               return new ResponseModel { Code = 0, Message = "CosServerException: " + serverEx.GetInfo() };

           }

       }


大文件分块上传


       /// <summary>

       /// 上传大文件、分块上传

       /// </summary>

       /// <param name="key"></param>

       /// <param name="srcPath"></param>

       /// <param name="progressCallback">委托,可用于显示分块信息</param>

       /// <param name="successCallback">委托,当任务成功时回调</param>

       /// <returns></returns>

       public async Task<ResponseModel> UpBigFile(string key, string srcPath, Action<long, long> progressCallback, Action<CosResult> successCallback)

       {

           ResponseModel responseModel = new ResponseModel();

           string bucket = _buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID


           TransferManager transferManager = new TransferManager(_cosXml, new TransferConfig());

           COSXMLUploadTask uploadTask = new COSXMLUploadTask(bucket, null, key);

           uploadTask.SetSrcPath(srcPath);

           uploadTask.progressCallback = delegate (long completed, long total)

           {

               progressCallback(completed, total);

               //Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total));

           };

           uploadTask.successCallback = delegate (CosResult cosResult)

           {

               COSXMLUploadTask.UploadTaskResult result = cosResult as COSXMLUploadTask.UploadTaskResult;

               successCallback(cosResult);

               responseModel.Code = 200;

               responseModel.Message = result.GetResultInfo();

           };

           uploadTask.failCallback = delegate (CosClientException clientEx, CosServerException serverEx)

           {

               if (clientEx != null)

               {

                   responseModel.Code = 0;

                   responseModel.Message = clientEx.Message;

               }

               if (serverEx != null)

               {

                   responseModel.Code = 0;

                   responseModel.Message = "CosServerException: " + serverEx.GetInfo();

               }

           };

           await Task.Run(() =>

           {

               transferManager.Upload(uploadTask);

           });

           return responseModel;

       }


查询对象列表


       public async Task<ResponseModel> SelectObjectList()

       {

           try

           {

               string bucket = _buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID

               GetBucketRequest request = new GetBucketRequest(bucket);

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //执行请求

               GetBucketResult result = await Task.FromResult(_cosXml.GetBucket(request));

               return new ResponseModel { Code = 200, Data = result.GetResultInfo() };

           }

           catch (CosClientException clientEx)

           {

               return new ResponseModel { Code = 0, Data = "CosClientException: " + clientEx.Message };

           }

           catch (CosServerException serverEx)

           {

               return new ResponseModel { Code = 0, Data = "CosServerException: " + serverEx.GetInfo() };

           }

       }


下载对象 、删除对象


       public async Task<ResponseModel> DownObject(string key, string localDir, string localFileName)

       {

           try

           {

               string bucket = _buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID

               GetObjectRequest request = new GetObjectRequest(bucket, key, localDir, localFileName);

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //设置进度回调

               request.SetCosProgressCallback(delegate (long completed, long total)

               {

                   Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total));

               });

               //执行请求

               GetObjectResult result = await Task.FromResult(_cosXml.GetObject(request));


               return new ResponseModel { Code = 200, Message = result.GetResultInfo() };

           }

           catch (CosClientException clientEx)

           {

               return new ResponseModel { Code = 0, Message = "CosClientException: " + clientEx.Message };

           }

           catch (CosServerException serverEx)

           {

               return new ResponseModel { Code = 0, Message = serverEx.GetInfo() };

           }

       }

       public async Task<ResponseModel> DeleteObject(string buketName)

       {

           try

           {

               string bucket = _buketName + "-" + _appid; //存储桶名称 格式:BucketName-APPID

               string key = "exampleobject"; //对象在存储桶中的位置,即称对象键.

               DeleteObjectRequest request = new DeleteObjectRequest(bucket, key);

               //设置签名有效时长

               request.SetSign(TimeUtils.GetCurrentTime(TimeUnit.SECONDS), 600);

               //执行请求

               DeleteObjectResult result = await Task.FromResult(_cosXml.DeleteObject(request));


               return new ResponseModel { Code = 200, Message = result.GetResultInfo() };

           }

           catch (CosClientException clientEx)

           {

               return new ResponseModel { Code = 0, Message = "CosClientException: " + clientEx.Message };

           }

           catch (CosServerException serverEx)

           {

               return new ResponseModel { Code = 0, Message = "CosServerException: " + serverEx.GetInfo() };

           }

       }


以上代码将官方示例作了优化。


   依赖于抽象、实现接口;

   松耦合;

   异步网络流、异步文件流;

   统一返回信息;

   增加匿名委托作方法参数;

   增加灵活性。


三,使用封装好的代码


1,初始化


官网示例文档:


使用修改后的代码,你可以这样初始化:


           var cosClient = new CosBuilder()

               .SetAccount("1252707544", " ap-guangzhou")

               .SetCosXmlServer()

               .SetSecret("AKIDEZohU6AmkeNTVPmedw65Ws462rVxLIpG", "Sn1iFi182jMARcheQ1gYIsGSROE5rSwG")

               .Builder();


简单测试代码


       static async Task Main(string[] args)

       {

           // 构建一个 CoxXmlServer 对象

           var cosClient = new CosBuilder()

               .SetAccount("125x707xx4", "ap-guangzhou")

               .SetCosXmlServer()

               .SetSecret("AKIxxxxxxedw65Ws462rVxLIpG", "Sn1iFi1xxxxxwG")

               .Builder();

           // 创建Cos连接客户端

           ICosClient client = new CosClient(cosClient, "125xx0xx44");

           // 创建一个存储桶

           var result = await client.CreateBucket("fsdgerer");

           Console.WriteLine("处理结果:" + result.Message);

           // 查询存储桶列表

           var c = await client.SelectBucket();

           Console.WriteLine(c.Message + c.Data);


           Console.ReadKey();

       }


运行结果(部分重要信息使用xx屏蔽):


处理结果:200 OK

Connection: keep-alive

Date: Fri, 09 Aug 2019 14:15:00 GMT

Server: tencent-cos

x-cos-request-id: xxxxxxxx=

Content-Length: 0


Success200 OK

Connection: keep-alive

Date: Fri, 09 Aug 2019 14:15:01 GMT

Server: tencent-cos

x-cos-request-id: xxxxxxx=

Content-Type: application/xml

Content-Length: 479


{ListAllMyBuckets:

{Owner:

ID:qcs::cam::uin/1586xx146:uin/158xxx2146

DisPlayName:158x2146

}

Buckets:

{Bucket:

Name:fsdgerer-125xxx7544

Location:ap-guangzhou

CreateDate:

}

{Bucket:

Name:work-1252xxx7544

Location:ap-guangzhou

CreateDate:

}

}

}