如何优雅地使用腾讯云COS-.NET篇

代码下载地址 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,记录 SecretIdSecretKey

记录 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:
}
}
}

其它不再赘述

最新文章

  1. Netty构建分布式消息队列实现原理浅析
  2. 理解WebService SOAP WSDL
  3. mongodb的一些小总结
  4. C-函数与内存剖析
  5. Entity Framework Power Tools
  6. ASP.NET MVC4中的Model验证 移除指定验证信息
  7. 列表:一个打了激素的数组3 - 零基础入门学习Python012
  8. JAVA基础知识面试题
  9. Django实现内容缓存
  10. MyEclipse中阿里JAVA代码规范插件(P3C)的安装及使用
  11. 安装STS报错(三)
  12. URL重定向漏洞,python打造URL重定向漏洞检测脚本
  13. Confluence 6 H2 数据库连接与合并整合
  14. spring mvc+mybatis 构建 cms + 实现UC浏览器文章功能
  15. 20155306 2016-2017-2 《Java程序设计》第九周学习总结
  16. arch/manjaro linux configuration
  17. java_继承、实现、依赖、关联、聚合、组合的代码表示
  18. javascript编码规范[原创]
  19. solr特点九:word(分词)
  20. 2018年10月19 手记 - 身为开发者的我de窘境

热门文章

  1. HashMap、ConcurrentHashMap解析
  2. 什么是POSP?系统逻辑是什么?pos收单必读
  3. .net连接Oracle
  4. logstash收集系统日志配置
  5. envoy的配置文件的样子
  6. c# 第31节 构造函数与析构函数、new关键字作用
  7. Javascript定时器只能执行一次
  8. luoguP3306 [SDOI2013]随机数生成器
  9. bolb与base64的图片互转
  10. 启动tomcat内存溢出