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