diff --git a/.gitignore b/.gitignore
index d9b94f5..a98bc64 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,5 +9,7 @@ QCloudCSharpSDK/COSXMLTests/obj
QCloudCSharpSDK/COSXMLTests/bin
QCloudCSharpSDK/COSXMLTests/TestResults
QCloudCSharpSDK/COSXMLTests/coveragereport
+QCloudCSharpSDK/NCOS
+QCloudCSharpSDK/.idea
*.vs
.vscode
diff --git a/QCloudCSharpSDK/COSXML/COSXML-Netcore.csproj b/QCloudCSharpSDK/COSXML/COSXML-Netcore.csproj
index c5bad93..4caf781 100644
--- a/QCloudCSharpSDK/COSXML/COSXML-Netcore.csproj
+++ b/QCloudCSharpSDK/COSXML/COSXML-Netcore.csproj
@@ -11,7 +11,7 @@
true
Tencent.QCloud.Cos.Sdk
- 5.4.35.0
+ 5.4.36.0
Tencent
Tencent
Tencent Cloud COS(Cloud Object Service) .Net SDK
diff --git a/QCloudCSharpSDK/COSXML/Common/CosVersion.cs b/QCloudCSharpSDK/COSXML/Common/CosVersion.cs
index 76648b1..55f1e90 100644
--- a/QCloudCSharpSDK/COSXML/Common/CosVersion.cs
+++ b/QCloudCSharpSDK/COSXML/Common/CosVersion.cs
@@ -9,7 +9,7 @@ namespace COSXML.Common
{
public sealed class CosVersion
{
- private static string SDKVersion = "5.4.35.0";
+ private static string SDKVersion = "5.4.36.0";
public static string GetUserAgent()
{
diff --git a/QCloudCSharpSDK/COSXML/Model/Bucket/BucketRequest.cs b/QCloudCSharpSDK/COSXML/Model/Bucket/BucketRequest.cs
index d8ad91d..e8d85ef 100644
--- a/QCloudCSharpSDK/COSXML/Model/Bucket/BucketRequest.cs
+++ b/QCloudCSharpSDK/COSXML/Model/Bucket/BucketRequest.cs
@@ -85,8 +85,29 @@ public override string GetHost()
.Append(".myqcloud.com");
}
}
-
- return hostBuilder.ToString();
+
+ String hostStr = hostBuilder.ToString();
+
+ if (userKeepDefaultDomain && !operationTimeOutRetry)
+ {
+ return hostStr;
+ }
+
+ if (operationTimeOutRetry || changeDefaultDomain)
+ {
+ StringBuilder pattern = new StringBuilder();
+ pattern.Append(".cos.").Append(region).Append(".myqcloud.com");
+ String patternStr = pattern.ToString();
+
+ if (hostStr.EndsWith(patternStr))
+ {
+ StringBuilder replace = new StringBuilder();
+ replace.Append(".cos.").Append(region).Append(".tencentcos.cn");
+ return hostStr.Replace(patternStr, replace.ToString());
+ }
+ }
+
+ return hostStr;
}
public override void CheckParameters()
diff --git a/QCloudCSharpSDK/COSXML/Model/CosRequest.cs b/QCloudCSharpSDK/COSXML/Model/CosRequest.cs
index b605817..db70df7 100644
--- a/QCloudCSharpSDK/COSXML/Model/CosRequest.cs
+++ b/QCloudCSharpSDK/COSXML/Model/CosRequest.cs
@@ -56,6 +56,12 @@ public abstract class CosRequest
///
protected bool needMD5 = true;
+ public bool userKeepDefaultDomain = false;
+
+ public bool changeDefaultDomain = false;
+
+ public bool operationTimeOutRetry = false;
+
///
/// 请求预签名URL
///
@@ -339,7 +345,8 @@ public virtual CosXmlSignSourceProvider GetSignSourceProvider()
"response-content-type",
"response-expires",
"transfer-encoding",
- "versionid"
+ "versionid",
+ "pic-operations"
});
foreach (KeyValuePair pair in headers)
diff --git a/QCloudCSharpSDK/COSXML/Model/Object/ObjectRequest.cs b/QCloudCSharpSDK/COSXML/Model/Object/ObjectRequest.cs
index 445dee3..bb089ac 100644
--- a/QCloudCSharpSDK/COSXML/Model/Object/ObjectRequest.cs
+++ b/QCloudCSharpSDK/COSXML/Model/Object/ObjectRequest.cs
@@ -114,8 +114,29 @@ public override string GetHost()
.Append(".myqcloud.com");
}
}
-
- return hostBuilder.ToString();
+
+ String hostStr = hostBuilder.ToString();
+
+ if (userKeepDefaultDomain && !operationTimeOutRetry)
+ {
+ return hostStr;
+ }
+
+ if (operationTimeOutRetry || changeDefaultDomain)
+ {
+ StringBuilder pattern = new StringBuilder();
+ pattern.Append(".cos.").Append(region).Append(".myqcloud.com");
+ String patternStr = pattern.ToString();
+
+ if (hostStr.EndsWith(patternStr))
+ {
+ StringBuilder replace = new StringBuilder();
+ replace.Append(".cos.").Append(region).Append(".tencentcos.cn");
+ return hostStr.Replace(patternStr, replace.ToString());
+ }
+ }
+
+ return hostStr;
}
public override void CheckParameters()
diff --git a/QCloudCSharpSDK/COSXML/Model/Object/PutObjectRequest.cs b/QCloudCSharpSDK/COSXML/Model/Object/PutObjectRequest.cs
index 5fef030..a6a06cf 100644
--- a/QCloudCSharpSDK/COSXML/Model/Object/PutObjectRequest.cs
+++ b/QCloudCSharpSDK/COSXML/Model/Object/PutObjectRequest.cs
@@ -212,6 +212,7 @@ public override Network.RequestBody GetRequestBody()
"stream offset + contentLength greater than stream.Length");
}
body = new StreamRequestBody(stream, fileOffset, contentLength);
+ body.ProgressCallback = progressCallback;
}
return body;
diff --git a/QCloudCSharpSDK/COSXML/Network/CommandTask.cs b/QCloudCSharpSDK/COSXML/Network/CommandTask.cs
index 762c5bb..2943ffa 100644
--- a/QCloudCSharpSDK/COSXML/Network/CommandTask.cs
+++ b/QCloudCSharpSDK/COSXML/Network/CommandTask.cs
@@ -9,6 +9,8 @@
using System.Reflection;
using System.IO;
using System.Net.Cache;
+using COSXML.CosException;
+using COSXML.Model.Tag;
namespace COSXML.Network
@@ -59,7 +61,7 @@ public static void Excute(Request request, Response response, HttpClientConfig c
httpWebRequest = HttpWebRequest.Create(request.RequestUrlString) as HttpWebRequest;
httpWebRequest.AllowWriteStreamBuffering = false;
-
+
//bind webRequest
request.BindHttpWebRequest(httpWebRequest);
@@ -77,7 +79,6 @@ public static void Excute(Request request, Response response, HttpClientConfig c
}
catch (WebException webEx)
{
-
if (webEx.Response != null && webEx.Response is HttpWebResponse)
{
//notify has been got response
@@ -149,9 +150,25 @@ private static void HandleHttpWebRequest(HttpWebRequest httpWebRequest, Request
private static void HandleHttpWebResponse(HttpWebResponse httpWebResponse, Response response)
{
HandleHttpWebResponseHeaders(response, httpWebResponse);
-
+ string requestId = httpWebResponse.GetResponseHeader("x-cos-request-id");
//handle body
- response.Body.HandleResponseBody(httpWebResponse.GetResponseStream());
+ if (requestId == String.Empty)
+ {
+ CosServerException cosServerException = new CosServerException((int)httpWebResponse.StatusCode, "request has error");
+ cosServerException.requestId = requestId;
+ throw cosServerException;
+ }
+
+ try
+ {
+ response.Body.HandleResponseBody(httpWebResponse.GetResponseStream());
+ }
+ catch (Exception ex)
+ {
+ CosServerException cosServerException = new CosServerException((int)httpWebResponse.StatusCode, ex.Message);
+ cosServerException.requestId = requestId;
+ throw cosServerException;
+ }
response.OnFinish(response.Code >= 200 && response.Code < 300, null);
@@ -312,6 +329,7 @@ public static void AsyncResponseCallback(IAsyncResult ar)
{
if (requestState.retryIndex < MaxRetries)
{
+ //重试
Schedue(requestState.request, requestState.response, config, requestState.retryIndex + 1);
return;
}
@@ -351,6 +369,7 @@ public static void AsyncResponseCallback(IAsyncResult ar)
{
if (requestState.retryIndex < MaxRetries)
{
+ //重试
Schedue(requestState.request, requestState.response, config, requestState.retryIndex + 1);
return;
}
diff --git a/QCloudCSharpSDK/COSXML/Network/HttpClient.cs b/QCloudCSharpSDK/COSXML/Network/HttpClient.cs
index 9f22225..d54b165 100644
--- a/QCloudCSharpSDK/COSXML/Network/HttpClient.cs
+++ b/QCloudCSharpSDK/COSXML/Network/HttpClient.cs
@@ -145,9 +145,13 @@ public void InternalExcute(CosRequest cosRequest, CosResult cosResult, QCloudCre
}
catch (CosServerException serverException)
{
- // 服务端5xx才重试
- if (serverException.statusCode >= 500 && retryIndex < MaxRetry)
+ // webCode >= 300
+ if (retryIndex < MaxRetry && serverException.statusCode >= 300)
{
+ if (serverException.requestId == String.Empty)
+ {
+ cosRequest.changeDefaultDomain = true;
+ }
InternalExcute(cosRequest, cosResult, credentialProvider, retryIndex + 1);
}
else
@@ -157,7 +161,7 @@ public void InternalExcute(CosRequest cosRequest, CosResult cosResult, QCloudCre
}
catch (CosClientException)
{
- // 客户端异常都重试
+ // 客户端异常都重试,如本地文件path写错则报警
if (retryIndex < MaxRetry)
{
InternalExcute(cosRequest, cosResult, credentialProvider, retryIndex + 1);
@@ -170,9 +174,17 @@ public void InternalExcute(CosRequest cosRequest, CosResult cosResult, QCloudCre
}
catch (Exception ex)
{
- // 未知异常也重试
- if (retryIndex < MaxRetry)
+ if (retryIndex < MaxRetry)//请求超时或者其它异常
{
+ bool isOperationTimeOu = ex.ToString().Contains("The operation has timed out");
+ if (isOperationTimeOu)
+ {
+ cosRequest.operationTimeOutRetry = true;
+ }
+ else
+ {
+ cosRequest.changeDefaultDomain = true;
+ }
InternalExcute(cosRequest, cosResult, credentialProvider, retryIndex + 1);
}
else
@@ -204,7 +216,7 @@ public void InternalExcute(CosRequest cosRequest, CosResult cosResult, QCloudCre
// }
// }
- public void InternalSchedue(CosRequest cosRequest, CosResult cosResult, COSXML.Callback.OnSuccessCallback successCallback, COSXML.Callback.OnFailedCallback failCallback, QCloudCredentialProvider credentialProvider)
+ public void InternalSchedue(CosRequest cosRequest, CosResult cosResult, COSXML.Callback.OnSuccessCallback successCallback, COSXML.Callback.OnFailedCallback failCallback, QCloudCredentialProvider credentialProvider, int retryIndex = 0)
{
try
@@ -230,7 +242,7 @@ public void InternalSchedue(CosRequest cosRequest, CosResult cosResult, COSXML.C
}
catch (CosServerException serverException)
{
- //throw serverException;
+ //throw clientException;
failCallback(null, serverException);
}
catch (CosClientException clientException)
@@ -416,7 +428,6 @@ public override void HandleResponseHeader()
cosResult.httpMessage = Message;
cosResult.responseHeaders = Headers;
cosResult.InternalParseResponseHeaders();
-
if (Code >= 300)
{
this.Body.ParseStream = PaserServerError;
@@ -431,9 +442,10 @@ public void PaserServerError(Stream inputStream, string contentType, long conten
{
CosServerException cosServerException = new CosServerException(cosResult.httpCode, cosResult.httpMessage);
List values;
-
+
Headers.TryGetValue("x-cos-request-id", out values);
cosServerException.requestId = (values != null && values.Count > 0) ? values[0] : null;
+
Headers.TryGetValue("x-cos-trace-id", out values);
cosServerException.traceId = (values != null && values.Count > 0) ? values[0] : null;
@@ -452,7 +464,6 @@ public void PaserServerError(Stream inputStream, string contentType, long conten
}
}
-
throw cosServerException;
}
diff --git a/QCloudCSharpSDK/COSXML/Transfer/COSXMLDownloadTask.cs b/QCloudCSharpSDK/COSXML/Transfer/COSXMLDownloadTask.cs
index 85152ff..7025842 100644
--- a/QCloudCSharpSDK/COSXML/Transfer/COSXMLDownloadTask.cs
+++ b/QCloudCSharpSDK/COSXML/Transfer/COSXMLDownloadTask.cs
@@ -1,15 +1,18 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Text;
using COSXML.Model.Object;
using COSXML.Utils;
using COSXML.Model;
using System.IO;
+using System.Linq;
using COSXML.Log;
using COSXML.CosException;
using System.Xml.Serialization;
using COSXML.Common;
using System.Threading;
+using System.Threading.Tasks;
namespace COSXML.Transfer
{
@@ -192,6 +195,21 @@ private void ComputeSliceList(HeadObjectResult result)
}
}
+ //重写原来的方法,里面通过使用同步接口多线程下载
+ internal void DownloadNew()
+ {
+ //获取文件的元信息
+ headObjectRequest = new HeadObjectRequest(bucket, key);
+ CosResult cosResult = cosXmlServer.HeadObject(headObjectRequest);
+ HeadObjectResult result = cosResult as HeadObjectResult;
+ //分片
+ ComputeSliceList(result);
+ //多线程下载
+ DownloadFileBySyncGetObjectFunc(result.crc64ecma, result.size);
+ }
+
+
+ //流式数据进行下载
internal void Download()
{
UpdateTaskState(TaskState.Waiting);
@@ -332,6 +350,163 @@ private bool CompareCrc64(string localFile, string crc64ecma)
}
}
+ ///
+ /// 多线程下载文件
+ ///
+ ///
+ private void MutisThreadsGetObject(long contentLength)
+ {
+ //将文件下载到cos-path的相对路径
+ DirectoryInfo dirInfo = new DirectoryInfo(localDir);
+ if (!dirInfo.Exists)
+ {
+ dirInfo.Create();
+ }
+ //缓存文件放在当前路径
+ ParallelOptions options = new ParallelOptions {
+ MaxDegreeOfParallelism = maxTasks
+ };
+ long completeLength = 0;
+ Parallel.ForEach(sliceList.Values, options, downloadedSlice =>
+ {
+ string tmpFileName = "." + localFileName + ".cosresumable." + downloadedSlice.partNumber;
+ lock (this.tmpFilePaths)
+ {
+ this.tmpFilePaths.Add(localDir+tmpFileName);
+ }
+ GetObjectRequest subGetObjectRequest = new GetObjectRequest(bucket, key, localDir, tmpFileName);
+ subGetObjectRequest.SetRange(downloadedSlice.sliceStart, downloadedSlice.sliceEnd);
+ getObjectResultToShow = cosXmlServer.GetObject(subGetObjectRequest);
+ completeLength += downloadedSlice.sliceEnd - downloadedSlice.sliceStart;
+ if (progressCallback != null && contentLength >= 0) {
+ progressCallback(completeLength, contentLength);
+ }
+ });
+ }
+
+ public GetObjectResult getObjectResultToShow;
+ private void DownloadFileBySyncGetObjectFunc(string crc64ecma, long contentLength)
+ {
+ try
+ {
+ //下载文件
+ MutisThreadsGetObject(contentLength);
+ //组装文件
+ MergeAllSliceAndCheckFile(crc64ecma);
+ //删除多余的隐藏的缓存文件
+ DeleteTmpFile(false);
+ }
+ catch (Exception e)
+ {
+ //销毁缓存文件,包含其中已经创建的最终文件
+ DeleteTmpFile(true);
+ throw;
+ }
+ //返回客户端信息,展示requestId等信息性
+ if (getObjectResultToShow == null)
+ {
+ getObjectResultToShow = new GetObjectResult();
+ }
+ DownloadTaskResult downloadTaskResult = new DownloadTaskResult();
+ downloadTaskResult.SetResult(getObjectResultToShow);
+ if (successCallback != null) {
+ successCallback(downloadTaskResult);
+ }
+ }
+
+ ///
+ /// 获取当前占用系统内存大小
+ ///
+ public void getMemorySize()
+ {
+ Process currentProcess = Process.GetCurrentProcess();
+ // 获取当前进程占用的内存大小(以字节为单位)
+ long memorySize = currentProcess.WorkingSet64;
+ // 将字节转换为兆字节(MB)
+ double memorySizeInMB = (double)memorySize / (1024 * 1024);
+ Console.WriteLine("内存大小是:" + memorySizeInMB + "MB");
+ }
+
+ public void DeleteTmpFile(bool hasException)
+ {
+ List tmpFileList = new List(this.tmpFilePaths);
+ foreach (var inputFilePath in tmpFileList)
+ {
+ System.IO.File.Delete(inputFilePath);
+ }
+ if (hasException && File.Exists(localDir + localFileName))
+ {
+ System.IO.File.Delete(localDir + localFileName);
+ }
+ }
+
+
+ public void MergeAllSliceAndCheckFile(string crc64ecma)
+ {
+ FileMode fileMode = FileMode.OpenOrCreate;
+ FileInfo localFileInfo = new FileInfo(localDir + localFileName);
+ if (localFileInfo.Exists && localFileOffset == 0 && localFileInfo.Length != rangeEnd - rangeStart + 1)
+ {
+ fileMode = FileMode.Truncate;
+ }
+
+ using (var outputStream = File.Open(localDir + localFileName, fileMode))
+ {
+ outputStream.Seek(localFileOffset, 0);
+ List tmpFileList = new List(this.tmpFilePaths);
+
+ tmpFileList.Sort(delegate(string x, string y)
+ {
+ int partNumber1 = int.Parse(x.Split(new string[] { "cosresumable." }, StringSplitOptions.None)[1]);
+ int partNumber2 = int.Parse(y.Split(new string[] { "cosresumable." }, StringSplitOptions.None)[1]);
+ return partNumber1 - partNumber2;
+ });
+
+ // 检查文件是否皆存在
+ foreach (var inputFilePath in tmpFileList)
+ {
+ if (!File.Exists(inputFilePath))
+ {
+ string msg = "local tmp file not exist, could be concurrent writing same file" + inputFilePath +
+ " download again";
+ COSXML.CosException.CosClientException clientEx = new COSXML.CosException.CosClientException((int)CosClientError.InternalError, msg );
+ throw clientEx;
+ }
+ }
+ //开始文件合并
+ foreach (var inputFilePath in tmpFileList)
+ {
+ using (var inputStream = File.OpenRead(inputFilePath))
+ {
+ FileInfo info = new FileInfo(inputFilePath);
+ inputStream.CopyTo(outputStream);
+ }
+ }
+ outputStream.Close();
+
+ // 合并完成后,默认进行文件大小的检查
+ FileInfo completedFileInfo = new FileInfo(localDir + localFileName);
+ if (completedFileInfo.Length != rangeEnd - rangeStart + 1)
+ {
+ string msg = "local File Length " + completedFileInfo.Length + " does not equals to applied download length " + (rangeEnd - rangeStart + 1) + ", try again";
+ COSXML.CosException.CosClientException clientEx = new COSXML.CosException.CosClientException((int)CosClientError.InternalError, msg);
+ throw clientEx;
+ }
+
+ // 按需进行CRC64的检查
+ if (enableCrc64Check)
+ {
+ if (!CompareCrc64(localDir + localFileName, crc64ecma))
+ {
+ COSXML.CosException.CosClientException clientEx = new COSXML.CosException.CosClientException
+ ((int)CosClientError.CRC64ecmaCheckFailed, "local File Crc64 does not equals to crc64ecma on cos, try download again");
+ throw clientEx;
+ }
+ }
+ }
+ }
+
+
// 发起多线程下载
private void ConcurrentGetObject(string crc64ecma)
{
diff --git a/QCloudCSharpSDK/COSXML/Transfer/COSXMLTask.cs b/QCloudCSharpSDK/COSXML/Transfer/COSXMLTask.cs
index 2eb8004..10bfd20 100644
--- a/QCloudCSharpSDK/COSXML/Transfer/COSXMLTask.cs
+++ b/QCloudCSharpSDK/COSXML/Transfer/COSXMLTask.cs
@@ -212,8 +212,9 @@ public class DownloadSliceStruct
public long sliceEnd;
public string eTag;
- }
+ public int taskStatus; //0,表示任务未开始,等待状态,1表示任务进行中,2表示任务完成
+ }
public enum TaskState
{
Waiting = 0,
diff --git a/QCloudCSharpSDK/COSXML/Transfer/TransferManager.cs b/QCloudCSharpSDK/COSXML/Transfer/TransferManager.cs
index 13b3ab5..e660182 100644
--- a/QCloudCSharpSDK/COSXML/Transfer/TransferManager.cs
+++ b/QCloudCSharpSDK/COSXML/Transfer/TransferManager.cs
@@ -76,7 +76,14 @@ public void Download(COSXMLDownloadTask downloader)
downloader.InitCosXmlServer(cosXml);
downloader.SetSliceSize(transferConfig.SliceSizeForDownload);
downloader.SetDivisionSize(transferConfig.DivisionForDownload);
- downloader.Download();
+ if (transferConfig.ByNewFunc)
+ {
+ downloader.DownloadNew();
+ }
+ else
+ {
+ downloader.Download();
+ }
}
///
@@ -139,6 +146,19 @@ public sealed class TransferConfig
// 10M
private long sliceSizeForDownload = 10485760;
+
+ //采取那种方式下载
+ private bool byNewFunc = false;
+
+ public bool ByNewFunc
+ {
+ get
+ {
+ return byNewFunc;
+ }
+ set { byNewFunc = value; }
+ }
+
///
/// 多大的文件会自动使用分片拷贝
///
diff --git a/QCloudCSharpSDK/COSXML/Utils/Crc64.cs b/QCloudCSharpSDK/COSXML/Utils/Crc64.cs
index b1eaa6e..9a310da 100644
--- a/QCloudCSharpSDK/COSXML/Utils/Crc64.cs
+++ b/QCloudCSharpSDK/COSXML/Utils/Crc64.cs
@@ -164,6 +164,35 @@ static public ulong Combine(ulong crc1, ulong crc2, long len2)
crc1 ^= crc2;
return crc1;
}
+
+ // 计算本地文件的crc64
+ public static string GetFileCrc64(string localFile)
+ {
+ Crc64.InitECMA();
+ using (FileStream fs = File.Open(localFile, FileMode.Open))
+ {
+ byte[] buffer = new byte[2048];
+ int bytesRead;
+ ulong crc = 0;
+
+ while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
+ {
+ ulong partCrc = Crc64.Compute(buffer, 0, bytesRead);
+ if (crc == 0)
+ {
+ crc = partCrc;
+ }
+ else
+ {
+ crc = Crc64.Combine(crc, partCrc, bytesRead);
+ }
+ }
+
+ string localFileCrc64 = crc.ToString();
+ return localFileCrc64;
+ }
+ }
+
public static bool CompareCrc64(string localFile, string crc64ecma)
{
diff --git a/QCloudCSharpSDK/NCOS/Program.cs b/QCloudCSharpSDK/NCOS/Program.cs
index 05022f3..5f5347d 100644
--- a/QCloudCSharpSDK/NCOS/Program.cs
+++ b/QCloudCSharpSDK/NCOS/Program.cs
@@ -2,16 +2,137 @@
using COSXML.Auth;
using COSXML.Transfer;
using System;
+using System.Diagnostics;
+using System.Text;
using COSXML;
using System.Threading.Tasks;
+using COSXML.CosException;
+using COSXML.Model;
using COSXML.Model.Tag;
using COSXML.Model.Bucket;
-
namespace Process
{
- public class Process
+ using COSXML.Model.Object;
+ using COSXML.Auth;
+ using COSXML.Transfer;
+ using System;
+ using COSXML;
+ using System.Threading.Tasks;
+
+ namespace COSSnippet
{
+ public class Process
+ {
+ private CosXml cosXml;
+
+ //永久密钥
+ string secretId = "";
+ string secretKey = "";
+ string region = "";
+ private string localPath = "./";
+ string bucket = "";//need
+
+ long DurationSecond = 24 * 60 * 60;
+
+ static void Main(string[] args)
+ {
+ Process Process = new Process();
+ Process.SetEnvironmentVariable();
+ Process.InitCosXml();
+ Process.DoSomething();
+ }
+
+ public void DoSomething()
+ {
+ Dictionary map = new Dictionary();
+ map["wewew"] = "hadn.zip";
+ foreach (var cospath in map)
+ {
+ TransferDownloadObject( cospath.Value, cospath.Key).Wait();
+ }
+ }
+
+
+ /// 高级接口下载对象
+ /// cosPath 对象在存储桶中的位置标识符,即称对象键
+ /// localFileName 指定本地保存的文件名
+ public async Task TransferDownloadObject(string cosPath, string localFileName)
+ {
+ // 初始化 TransferConfig
+ TransferConfig transferConfig = new TransferConfig();
+ // 手动设置高级下载接口的分块阈值为 20MB(默认为20MB), 从5.4.26版本开始支持!
+ transferConfig.DivisionForDownload = 3 * 1024 * 1024;
+ // 手动设置高级下载接口的分块大小为 10MB(默认为5MB),不建议此处设置过小的分块值,可能导致频繁重试或下载速度不合预期
+ transferConfig.SliceSizeForDownload = 2 * 1024 * 1024;
+
+ transferConfig.ByNewFunc = true;
+
+ // 初始化 TransferManager
+ TransferManager transferManager = new TransferManager(cosXml, transferConfig);
+
+ // 下载对象
+ COSXMLDownloadTask downloadTask = new COSXMLDownloadTask(bucket, cosPath, localPath, localFileName);
+ // 手动设置高级下载接口的并发数 (默认为5), 从5.4.26版本开始支持!
+ downloadTask.SetMaxTasks(16);
+ downloadTask.progressCallback = delegate(long completed, long total)
+ {
+ Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total));
+ };
+ try
+ {
+ COSXML.Transfer.COSXMLDownloadTask.DownloadTaskResult result = await transferManager.DownloadAsync(downloadTask);
+ Console.WriteLine(result.GetResultInfo());
+ string eTag = result.eTag;
+ }
+ catch (COSXML.CosException.CosClientException clientEx)
+ {
+ //请求失败
+ Console.WriteLine("CosClientException: " + clientEx);
+ }
+ catch (COSXML.CosException.CosServerException serverEx)
+ {
+ //请求失败
+ Console.WriteLine("CosServerException: " + serverEx.GetInfo());
+ }
+ }
+
+ ///
+ /// 初始化CosXml
+ ///
+ public void InitCosXml()
+ {
+ region = Environment.GetEnvironmentVariable("COS_REGION");
+ secretId = Environment.GetEnvironmentVariable("SECRET_ID");
+ secretKey = Environment.GetEnvironmentVariable("SECRET_KEY");
+ if (secretId == null)
+ {
+ secretId = Environment.GetEnvironmentVariable("SECRET_ID", EnvironmentVariableTarget.Machine);
+ secretKey = Environment.GetEnvironmentVariable("SECERT_KEY", EnvironmentVariableTarget.Machine);
+ }
+
+ CosXmlConfig config = new CosXmlConfig.Builder()
+ .SetRegion(region)
+ .SetDebugLog(true)
+ .IsHttps(false)
+ .SetConnectionTimeoutMs(5000)
+ .SetReadWriteTimeoutMs(5000)
+ .Build();
+ QCloudCredentialProvider qCloudCredentialProvider =
+ new DefaultQCloudCredentialProvider(secretId, secretKey, DurationSecond);
+ cosXml = new CosXmlServer(config, qCloudCredentialProvider);
+ }
+
+ ///
+ /// 设置环境变量
+ ///
+ public void SetEnvironmentVariable()
+ {
+ Environment.SetEnvironmentVariable("COS_REGION", "");//need
+ Environment.SetEnvironmentVariable("SECRET_ID", "");//need
+ Environment.SetEnvironmentVariable("SECRET_KEY", "");//need
+ }
+ }
}
}
\ No newline at end of file