如何優雅地使用騰訊雲COS-.NET篇

如何優雅地使用騰訊雲COS-.NET篇

代碼下載地址 https://github.com/whuanle/txypx20190809git

前提

建立子帳號github

打開 https://console.cloud.tencent.com/camshell

建立子用戶,設置子帳號策略爲 AdministratorAccess ,或者參考https://cloud.tencent.com/document/product/436/11714 ,添加訪問 COS 的權限 記錄子用戶的 帳號ID編程

切換子用戶登陸。c#

添加 appid 密鑰api

打開 https://console.cloud.tencent.com/cam/capi網絡

新建 API 密鑰,記錄下 appid,記錄 SecretIdSecretKeyapp

記錄 Region異步

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

能夠查詢可用區/地域的 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;
            }
        }
    }
}

概覽:

1565341618

可是大神說,這樣很差,程序要高內聚、低耦合,依賴與抽象而不依賴於具體實現。

那怎麼辦?只能修改一下。

二,優化

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,初始化

官網示例文檔:

1565356983(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:
}
}
}

其它再也不贅述

相關文章
相關標籤/搜索