详情页标题前

阿里云对象存储OSS.NET分片上传-云淘科技

详情页1

OSS提供的分片上传(Multipart Upload)功能,将要上传的较大文件(Object)分成多个分片(Part)来分别上传,上传完成后再调用CompleteMultipartUpload接口将这些Part组合成一个Object来达到断点续传的效果。

注意事项

  • 本文以华东1(杭州)外网Endpoint为例。如果您希望通过与OSS同地域的其他阿里云产品访问OSS,请使用内网Endpoint。关于OSS支持的Region与Endpoint的对应关系,请参见访问域名和数据中心。
  • 本文以OSS域名新建OSSClient为例。如果您希望通过自定义域名、STS等方式新建OSSClient,请参见.NET初始化。
  • 要分片上传,您必须有oss:PutObject权限。具体操作,请参见为RAM用户授权自定义的权限策略。

分片上传流程

分片上传(Multipart Upload)分为以下三个步骤:

  1. 初始化一个分片上传事件。

    调用InitiateMultipartUploadRequest方法返回OSS创建的全局唯一的uploadId。

  2. 上传分片。

    调用UploadPartRequest方法上传分片数据。

    说明

    • 对于同一个uploadId,分片号(PartNumber)标识了该分片在整个文件内的相对位置。如果使用同一个分片号上传了新的数据,则OSS上该分片已有的数据将会被覆盖。

    • OSS将收到的分片数据的MD5值放在ETag头内返回给用户。

    • OSS计算上传数据的MD5值,并与SDK计算的MD5值比较,如果不一致则返回InvalidDigest错误码。

  3. 完成分片上传。

    所有分片上传完成后,调用CompleteMultipartUploadRequest方法将所有分片合并成完整的文件。

分片上传完整示例

以下通过一个完整的示例对分片上传的流程进行逐步解析:

using Aliyun.OSS;

// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填写Bucket名称。
var bucketName = "examplebucket";
// 填写Object完整路径。Object完整路径中不能包含Bucket名称。
var objectName = "exampleobject.txt";
// 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。
var localFilename = "D:\localpath\examplefile.txt";
// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);

// 初始化分片上传,返回uploadId。
var uploadId = "";
try
{
    // 定义上传的文件及所属Bucket的名称。您可以在InitiateMultipartUploadRequest中设置ObjectMeta,但不必指定其中的ContentLength。
    var request = new InitiateMultipartUploadRequest(bucketName, objectName);
    var result = client.InitiateMultipartUpload(request);
    uploadId = result.UploadId;
    // 打印UploadId。
    Console.WriteLine("Init multi part upload succeeded");
    // 根据uploadId执行取消分片上传事件或者列举已上传分片的操作。
    // 如果您需要根据您需要uploadId执行取消分片上传事件的操作,您需要在调用InitiateMultipartUpload完成初始化分片之后获取uploadId。 
    // 如果您需要根据您需要uploadId执行列举已上传分片的操作,您需要在调用InitiateMultipartUpload完成初始化分片之后,且在调用CompleteMultipartUpload完成分片上传之前获取uploadId。
    Console.WriteLine("Upload Id:{0}", result.UploadId);
}
catch (Exception ex)
{
    Console.WriteLine("Init multi part upload failed, {0}", ex.Message);
}
// 计算分片总数。
var partSize = 100 * 1024;
var fi = new FileInfo(localFilename);
var fileSize = fi.Length;
var partCount = fileSize / partSize;
if (fileSize % partSize != 0)
{
    partCount++;
}
// 开始分片上传。PartETags是保存PartETag的列表,OSS收到用户提交的分片列表后,会逐一验证每个分片数据的有效性。当所有的数据分片通过验证后,OSS会将这些分片组合成一个完整的文件。
var partETags = new List();
try
{
    using (var fs = File.Open(localFilename, FileMode.Open))
    {
        for (var i = 0; i < partCount; i++)
        {
            var skipBytes = (long)partSize * i;
            // 定位到本次上传的起始位置。
            fs.Seek(skipBytes, 0);
            // 计算本次上传的分片大小,最后一片为剩余的数据大小。
            var size = (partSize < fileSize - skipBytes) ? partSize : (fileSize - skipBytes);
            var request = new UploadPartRequest(bucketName, objectName, uploadId)
            {
                InputStream = fs,
                PartSize = size,
                PartNumber = i + 1
            };
            // 调用UploadPart接口执行上传功能,返回结果中包含了这个数据片的ETag值。
            var result = client.UploadPart(request);
            partETags.Add(result.PartETag);
            Console.WriteLine("finish {0}/{1}", partETags.Count, partCount);
        }
        Console.WriteLine("Put multi part upload succeeded");
    }
}
catch (Exception ex)
{
    Console.WriteLine("Put multi part upload failed, {0}", ex.Message);
}
// 完成分片上传。
try
{
    var completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, objectName, uploadId);
    foreach (var partETag in partETags)
    {
        completeMultipartUploadRequest.PartETags.Add(partETag);
    }
    var result = client.CompleteMultipartUpload(completeMultipartUploadRequest);
    Console.WriteLine("complete multi part succeeded");
}
catch (Exception ex)
{
    Console.WriteLine("complete multi part failed, {0}", ex.Message);
}

取消分片上传事件

您可以调用client.AbortMultipartUpload方法来取消分片上传事件。当一个分片上传事件被取消后,无法再使用这个uploadId做任何操作,已经上传的分片数据会被删除。

以下代码用于取消分片上传事件。

using Aliyun.OSS;

// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填写Bucket名称。
var bucketName = "examplebucket";
// 填写Object完整路径。Object完整路径中不能包含Bucket名称。
var objectName = "exampleobject.txt";
// 填写uploadId。uploadId来源于调用InitiateMultipartUpload完成初始化分片之后的返回结果。
var uploadId = "yourUploadId";

// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
// 初始化分片上传。
try
{
    var request = new InitiateMultipartUploadRequest(bucketName, objectName);
    var result = client.InitiateMultipartUpload(request);
    uploadId = result.UploadId;
    // 打印uploadId。
    Console.WriteLine("Init multi part upload succeeded");
    Console.WriteLine("Upload Id:{0}", result.UploadId);
}
catch (Exception ex)
{
    Console.WriteLine("Init multi part upload failed, {0}", ex.Message);
}
// 取消分片上传。
try
{
    var request = new AbortMultipartUploadRequest(bucketName, objectName, uploadId);
    client.AbortMultipartUpload(request);
    Console.WriteLine("Abort multi part succeeded, {0}", uploadId);
}
catch (Exception ex)
{
    Console.WriteLine("Abort multi part failed, {0}", ex.Message);
}

列举已上传的分片

以下代码用于列举已上传的分片:

using Aliyun.OSS;
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填写Bucket名称。
var bucketName = "examplebucket";
// 填写Object完整路径。Object完整路径中不能包含Bucket名称。
var objectName = "exampleobject.txt";
// 填写uploadId。uploadId来源于调用InitiateMultipartUpload完成初始化分片之后,且在调用CompleteMultipartUpload完成分片上传之前的返回结果。
var uploadId = "yourUploadId";

// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    PartListing listPartsResult = null;
    var nextMarker = 0;
    do 
    {
        var listPartsRequest = new ListPartsRequest(bucketName, objectName, uploadId) 
        {
            PartNumberMarker = nextMarker,
        };
        // 列举已上传的分片。
        listPartsResult = client.ListParts(listPartsRequest);
        Console.WriteLine("List parts succeeded");
        // 遍历所有分片。
        var parts = listPartsResult.Parts;
        foreach (var part in parts)
        {
            Console.WriteLine("partNumber: {0}, ETag: {1}, Size: {2}", part.PartNumber, part.ETag, part.Size);
        }
        nextMarker = listPartsResult.NextPartNumberMarker;
    } while (listPartsResult.IsTruncated);
}
catch (Exception ex)
{
    Console.WriteLine("List parts failed, {0}", ex.Message);
}

列举分片上传事件

调用ossClient.listMultipartUploads方法列举出所有执行中的分片上传事件,即已初始化但尚未完成或已取消的分片上传事件。可设置的参数如下:

参数

作用

设置方法

prefix

限定返回的文件名称必须以指定的prefix作为前缀。注意使用prefix查询时,返回的文件名称中仍会包含prefix。

ListMultipartUploadsRequest.setPrefix(String prefix)

delimiter

用于对文件名称进行分组的一个字符。所有名称包含指定的前缀且第一次出现delimiter字符之间的文件作为一组元素。

ListMultipartUploadsRequest.setDelimiter(String delimiter)

maxUploads

限定此次返回分片上传事件的最大数目,默认值和最大值均为1000。

ListMultipartUploadsRequest.setMaxUploads(Integer maxUploads)

keyMarker

所有文件名称的字母序大于keyMarker参数值的分片上传事件。可以与uploadIdMarker参数一同使用来指定返回结果的起始位置。

ListMultipartUploadsRequest.setKeyMarker(String keyMarker)

uploadIdMarker

与keyMarker参数一同使用来指定返回结果的起始位置。 如果未设置keyMarker参数,则此参数无效。如果设置了keyMarker参数,则查询结果中包含:

  • 名称的字母序大于keyMarker参数值的所有文件。

  • 文件名称等于keyMarker参数值且uploadId比uploadIdMarker参数值大的所有分片上传事件。

ListMultipartUploadsRequest.setUploadIdMarker(String uploadIdMarker)

以下代码用于列举分片上传事件。

using Aliyun.OSS;
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填写Bucket名称。
var bucketName = "examplebucket";

// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    MultipartUploadListing multipartUploadListing = null;
    var nextMarker = string.Empty;
    do
    {
        // 列举分片上传事件。
        var request = new ListMultipartUploadsRequest(bucketName)
        {
            KeyMarker = nextMarker,
        };
        multipartUploadListing = client.ListMultipartUploads(request);
        Console.WriteLine("List multi part succeeded");
        // 列举各个分片上传事件的信息。
        foreach (var mu in multipartUploadListing.MultipartUploads)
        {
            Console.WriteLine("Key: {0},  UploadId: {1}", mu.Key, mu.UploadId);
        }
        // 返回结果中isTruncated为false,nextKeyMarker和nextUploadIdMarker作为下次读取的起点。
        nextMarker = multipartUploadListing.NextKeyMarker;
    } while (multipartUploadListing.IsTruncated);
}
catch (Exception ex)
{
    Console.WriteLine("List multi part uploads failed, {0}", ex.Message);
}

指定前缀和最大返回条数

以下代码通过指定前缀和最大返回条数来进行分片上传:

using Aliyun.OSS;
// yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "yourEndpoint";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填写Bucket名称。
var bucketName = "examplebucket";

// 定义前缀。
var prefix = "yourObjectPrefix";
// 定义最大返回条数为100。
var maxUploads = 100;
// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
    MultipartUploadListing multipartUploadListing = null;
    var nextMarker = string.Empty;
    do
    {
        // 列举分片上传事件。默认列举1000个分片。
        var request = new ListMultipartUploadsRequest(bucketName)
        {
            KeyMarker = nextMarker,
            // 指定前缀。
            Prefix = prefix,
            // 指定最大返回条数。
            MaxUploads = maxUploads,
        };
        multipartUploadListing = client.ListMultipartUploads(request);
        Console.WriteLine("List multi part succeeded");
        // 列举各个分片上传事件的信息。
        foreach (var mu in multipartUploadListing.MultipartUploads)
        {
            Console.WriteLine("Key: {0},  UploadId: {1}", mu.Key, mu.UploadId);
        }
        nextMarker = multipartUploadListing.NextKeyMarker;
    } while (multipartUploadListing.IsTruncated);
}
catch (Exception ex)
{
    Console.WriteLine("List multi part uploads failed, {0}", ex.Message);
}

相关文档

  • 关于分片上传的完整示例代码,请参见GitHub示例。

  • 分片上传的完整实现涉及三个API接口,详情如下:

    • 关于初始化分片上传事件的API接口说明,请参见InitiateMultipartUpload。

    • 关于分片上传Part的API接口说明,请参见UploadPart。

    • 关于完成分片上传的API接口说明,请参见CompleteMultipartUpload。

  • 关于取消分片上传事件的API接口说明,请参见AbortMultipartUpload。

  • 关于列举已上传分片的API接口说明,请参见ListParts。

  • 关于列举所有执行中的分片上传事件(即已初始化但尚未完成或已取消的分片上传事件)的API接口说明,请参见ListMultipartUploads。

内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家

阿里云企业补贴进行中: 马上申请

腾讯云限时活动1折起,即将结束: 马上收藏

同尘科技为腾讯云授权服务中心。

购买腾讯云产品享受折上折,更有现金返利:同意关联,立享优惠

转转请注明出处:https://www.yunxiaoer.com/158446.html

(0)
上一篇 2023年12月10日
下一篇 2023年12月10日
详情页2

相关推荐

  • 阿里云对象存储OSS传输加速-云淘科技

    OSS传输加速利用全球分布的云机房,将全球各地用户对您存储空间(Bucket)的访问,经过智能路由解析至就近的接入点,使用优化后的网络及协议,为云存储互联网的上传、下载提供端到端的加速方案。 使用场景 远距离数据传输加速 例如全球性的论坛、Top在线协同办公平台等,部分客户会因传输距离较远导致上传和下载体验非常差。传输加速功能可以让全球各地的客户使用优化后的…

    阿里云对象存储 2023年12月10日
  • 阿里云对象存储OSSPHP下载文件概述-云淘科技

    文件下载的完整代码请参见GitHub。 OSS PHP SDK提供了丰富的文件下载方式: 下载OSS文件到本地文件 下载OSS文件到本地内存 范围下载 限定条件下载 内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家阿里云企业补贴进行中: 马上申请腾讯云限时活动1折起,即将结束: 马上收藏同尘科技为腾讯云授权服务中心。 购买腾讯云产品享受折上折,更…

    阿里云对象存储 2023年12月10日
  • 信息流广告,信息流部分建议宽度830px,只针对默认列表样式,顺序随机
  • 阿里云对象存储OSS0048-00000109-云淘科技

    问题描述 使用浏览器通过OSS传输加速域名访问文件时,可能会出现无法预览而是直接下载的现象。 问题原因 在2021/01/08 18:00之后开通传输加速的Bucket,使用OSS传输加速域名访问任意文件,OSS会在返回头中增加两个Header: x-oss-force-download:true Content-Disposition: attachmen…

    阿里云对象存储 2023年12月10日
  • 阿里云对象存储OSS音频转码-云淘科技

    您可以通过音频转码功能,将音频转换为需要的格式。本文介绍音频转码处理功能参数及示例。 注意事项 音频转码仅支持异步处理(x-oss-async-process处理方式)。 使用音频转码前,需要先绑定IMM Project。关于控制台和API如何绑定,请参见快速入门和AttachOSSBucket。 不支持匿名访问。 必须拥有IMM处理所需的相关权限。更多信息…

    阿里云对象存储 2023年12月10日
  • 阿里云对象存储OSS使用REST API发起请求-云淘科技

    您可以直接发起REST API请求。使用REST API发起请求适用于对程序自定义要求较高的场景。您需要手动编写代码计算签名并将签名添加到REST API请求中。OSS仅支持虚拟托管(Virtual Hosted)风格的REST API请求。 OSS域名构成规则 针对OSS的网络请求,除了GetService(ListBuckets)以及DescribeRe…

    阿里云对象存储 2023年12月10日

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
本站为广大会员提供阿里云、腾讯云、华为云、百度云等一线大厂的购买,续费优惠,保证底价,买贵退差。