开发者社区 问答 正文

.NET-SDK之如何实现上传文件(四)?


Upload Part本地上传


我们把本地文件分片上传。假设有一个文件,本地路径为 /path/to/file.zip 由于文件比较大,我们将其分片传输到OSS中。

  1. using Aliyun.OSS;
  2. // 初始化OssClient
  3. var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
  4. // 计算片个数
  5. var fi = new FileInfo(fileToUpload);
  6. var fileSize = fi.Length;
  7. var partCount = fileSize / partSize;
  8. if (fileSize % partSize != 0)
  9. {
  10.      partCount++;
  11. }
  12. // 开始分片上传
  13. try
  14. {
  15.     var partETags = new List<PartETag>();
  16.     using (var fs = File.Open(fileToUpload, FileMode.Open))
  17.     {
  18.         for (var i = 0; i < partCount; i++)
  19.         {
  20.             var skipBytes = (long)partSize * i;
  21.             //定位到本次上传片应该开始的位置
  22.             fs.Seek(skipBytes, 0);
  23.             //计算本次上传的片大小,最后一片为剩余的数据大小,其余片都是part size大小。
  24.             var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
  25.             var request = new UploadPartRequest(bucketName, objectName, uploadId)
  26.             {
  27.                 InputStream = fs,
  28.                 PartSize = size,
  29.                 PartNumber = i + 1
  30.             };
  31.             //调用UploadPart接口执行上传功能,返回结果中包含了这个数据片的ETag值
  32.             var result = _ossClient.UploadPart(request);
  33.             partETags.Add(result.PartETag);
  34.         }
  35.         Console.WriteLine("Put multi part upload succeeded");
  36.     }
  37. }
  38. catch (Exception ex)
  39. {
  40.     Console.WriteLine("Put multi part upload failed, {0}", ex.Message);
  41. }

说明: 完整代码参考 GitHub

上面程序的核心是调用UploadPart方法来上传每一个分片,但是要注意以下几点:
  • UploadPart 方法要求除最后一个Part以外,其他的Part大小都要大于100KB。但是Upload Part接口并不会立即校验上传Part的大小(因为不知道是否为最后一片);只有当Complete Multipart Upload的时候才会校验。
  • OSS会将服务器端收到Part数据的MD5值放在ETag头内返回给用户。
  • 为了保证数据在网络传输过程中不出现错误,SDK会自动设置Content-MD5,OSS会计算上传数据的MD5值与SDK计算的MD5值比较,如果不一致返回InvalidDigest错误码。
  • Part号码的范围是1~10000。如果超出这个范围,OSS将返回InvalidArgument的错误码。
  • 每次上传part时都要把流定位到此次上传片开头所对应的位置。
  • 每次上传part之后,OSS的返回结果会包含一个 PartETag 对象,他是上传片的ETag与片编号(PartNumber)的组合,在后续完成分片上传的步骤中会用到它,因此我们需要将其保存起来。一般来讲我们将这些 PartETag 对象保存到List中。


完成分片上传


完成分片上传代码如下:
  1. using Aliyun.OSS;
  2. // 初始化OssClient
  3. var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
  4. try
  5. {
  6.     var completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, key, uploadId);
  7.     foreach (var partETag in partETags)
  8.     {
  9.         completeMultipartUploadRequest.PartETags.Add(partETag);
  10.     }
  11.     var result = client.CompleteMultipartUpload(completeMultipartUploadRequest);
  12.     Console.WriteLine("complete multi part succeeded");
  13. }
  14. catch (Exception ex)
  15. {
  16.     Console.WriteLine("complete multi part failed, {0}", ex.Message);
  17. }

说明:
  • 完整代码参考GitHub
  • 上面代码中的 partETags 就是进行分片上传中保存的partETag的列表,OSS收到用户提交的Part列表后,会逐一验证每个数据Part的有效性。
  • 当所有的数据Part验证通过后,OSS会将这些part组合成一个完整的文件。


取消分片上传事件


我们可以用 AbortMultipartUpload 方法取消分片上传。
  1. using Aliyun.OSS;
  2. // 初始化OssClient
  3. var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
  4. try
  5. {
  6.     var request = new AbortMultipartUpload(bucketName, key, uploadId);
  7.     client.AbortMultipartUpload(request);
  8.     Console.WriteLine("Abort multi part succeeded");
  9. }
  10. catch (Exception ex)
  11. {
  12.     Console.WriteLine("Abort multi part failed, {0}", ex.Message);
  13. }

说明: 完整代码参考请 GitHub

展开
收起
青衫无名 2017-10-18 15:00:32 1726 分享 版权
0 条回答
写回答
取消 提交回答