复制与移动对象

最近更新时间:2024-08-14 18:05:41

我的收藏

简介

本文介绍对象存储 COS 通过 .NET(C#) SDK 实现复制与移动对象功能的示例代码和描述。包括高级接口、简单操作、分块操作三个部分。

注意事项

若您使用简单接口复制对象,需要具有源对象的读权限和目标对象的写权限:在您进行 授权策略 时,目标对象的授权 action 需要设置为cos:PutObject ,源对象的授权 action 需要设置为cos:GetObject ,更多授权请参见 支持CAM的业务接口
若您使用高级接口的自动分块复制或使用简单接口的分块操作实现分块复制,需要具有源对象的读权限以及目标对象的初始化分块上传、上传对象、完成分块上传的权限:在您进行 授权策略 时,目标对象的授权 action 需要设置为 cos:InitiateMultipartUploadcos:PutObjectcos:CompleteMultipartUpload,源对象的授权 action 需要设置为cos:GetObject ,更多授权请参见 支持CAM的业务接口

相关示例

功能名称
描述
示例代码
高级接口
高级接口封装了简单拷贝、分块拷贝接口,根据文件大小智能的选择拷贝对象的方式。
简单操作
简单操作的拷贝接口可以拷贝一个对象至指定存储桶中,不支持自动分块拷贝。最大支持拷贝不超过5GB的对象,5GB以上对象请使用 分块拷贝 或 高级接口 拷贝。
分块操作
分块操作基于多个简单接口可以实现将整个源对象切分为多个分块,然后再将这些分块拷贝到目标存储桶中。

前期准备:初始化 COS 服务实例

public class ObjectModel { private CosXml cosXml; //将服务用户设置成数据成员 // 初始化COS服务实例 private void InitCosXml() { string region = Environment.GetEnvironmentVariable("COS_REGION"); CosXmlConfig config = new CosXmlConfig.Builder() .SetRegion(region) // 设置默认的地域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224 .Build(); string secretId = Environment.GetEnvironmentVariable("SECRET_ID"); // 云 API 密钥 SecretId, 获取 API 密钥请参照 https://console.cloud.tencent.com/cam/capi string secretKey = Environment.GetEnvironmentVariable("SECRET_KEY"); // 云 API 密钥 SecretKey, 获取 API 密钥请参照 https://console.cloud.tencent.com/cam/capi long durationSecond = 600; //每次请求签名有效时长,单位为秒 QCloudCredentialProvider qCloudCredentialProvider = new DefaultQCloudCredentialProvider(secretId, secretKey, durationSecond); this.cosXml = new CosXmlServer(config, qCloudCredentialProvider); } }

高级接口(推荐)

高级接口封装了简单复制、分块复制接口的异步请求,并支持暂停、恢复以及取消复制请求。
说明:
对象大小小于分块阈值时选择简单复制,超过阈值时使用分块复制,阈值支持用户自行配置,默认为5MB。
分块大小支持用户自行配置,默认为2MB。

使用高级接口复制

public async Task TransferCopyObject() { TransferConfig transferConfig = new TransferConfig(); //手动设置分块复制阈值,小于阈值的对象使用简单复制,大于阈值的对象使用分块复制,不设定则默认为5MB transferConfig.DdivisionForCopy = 5242880; //手动设置高级接口的自动分块大小,不设定则默认为2MB transferConfig.SliceSizeForCopy = 2097152; // 初始化 TransferManager TransferManager transferManager = new TransferManager(cosXml, transferConfig); string sourceAppid = "1250000000"; //账号 appid string sourceBucket = "sourcebucket-1250000000"; //"源对象所在的存储桶 string sourceRegion = "COS_REGION"; //源对象的存储桶所在的地域 string sourceKey = "sourceObject"; //源对象键 //构造源对象属性 CopySourceStruct copySource = new CopySourceStruct(sourceAppid, sourceBucket, sourceRegion, sourceKey); string bucket = "examplebucket-1250000000"; //目标存储桶,格式:BucketName-APPID string key = "exampleobject"; //目标对象的对象键 COSXMLCopyTask copytask = new COSXMLCopyTask(bucket, key, copySource); try { COSXML.Transfer.COSXMLCopyTask.CopyTaskResult result = await transferManager.CopyAsync(copytask); 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()); } }

简单操作

复制对象时保留对象属性

复制文件到目标路径(PUT Object - Copy)。复制对象接口,能够在复制请求中设置修改对象属性及元数据,并且支持原地复制,即能够支持原地修改对象元数据的特性。
public void SimpleCopyObject()
{
try
{
string sourceAppid = "1250000000"; //账号 appid
string sourceBucket = "sourcebucket-1250000000"; //"源对象所在的存储桶
string sourceRegion = "COS_REGION"; //源对象的存储桶所在的地域
string sourceKey = "sourceObject"; //源对象键
//构造源对象属性
CopySourceStruct copySource = new CopySourceStruct(sourceAppid, sourceBucket, sourceRegion, sourceKey);
// 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer
string bucket = "examplebucket-1250000000";
string key = "exampleobject"; //对象键
CopyObjectRequest request = new CopyObjectRequest(bucket, key);
//设置拷贝源
request.SetCopySource(copySource);
//设置是否拷贝还是更新,此处是拷贝
request.SetCopyMetaDataDirective(COSXML.Common.CosMetaDataDirective.Copy);
//执行请求
CopyObjectResult result = cosXml.CopyObject(request);
//请求成功
Console.WriteLine(result.GetResultInfo());
}
catch (COSXML.CosException.CosClientException clientEx)
{
Console.WriteLine("CosClientException: " + clientEx);
}
catch (COSXML.CosException.CosServerException serverEx)
{
Console.WriteLine("CosServerException: " + serverEx.GetInfo());
}
}

修改对象存储类型

标准存储可以修改为低频存储、智能分层存储、归档存储和深度归档存储等。如果希望将归档存储或深度归档存储的对象修改为其他存储类型,首先需要使用 PostRestore 将归档存储或深度归档存储的对象回热,才能使用该接口请求修改存储类型。关于存储类型的详细说明请参见 存储类型概述
public void CopyChangeStorageClass() { try { // 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer string bucket = "examplebucket-1250000000"; string key = "exampleobject"; //对象键 string appId = "1250000000"; //账号 appid string region = "COS_REGION"; //源对象的存储桶所在的地域 //构造对象属性 CopySourceStruct copySource = new CopySourceStruct(appId, bucket, region, key);
//构造请求request CopyObjectRequest request = new CopyObjectRequest(bucket, key); //设置拷贝源 request.SetCopySource(copySource); //设置是否拷贝还是更新,此处是拷贝 request.SetCopyMetaDataDirective(COSXML.Common.CosMetaDataDirective.Replaced); // 修改为归档存储 request.SetCosStorageClass("ARCHIVE"); //执行请求 CopyObjectResult result = cosXml.CopyObject(request); //请求成功 Console.WriteLine(result.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { Console.WriteLine("CosClientException: " + clientEx); } catch (COSXML.CosException.CosServerException serverEx) { Console.WriteLine("CosServerException: " + serverEx.GetInfo()); } }


复制对象时替换对象属性

public void CopyChangeAttr() { try { string sourceAppid = "1250000000"; //账号 appid string sourceBucket = "sourcebucket-1250000000"; //"源对象所在的存储桶 string sourceRegion = "COS_REGION"; //源对象的存储桶所在的地域 string sourceKey = "sourceObject"; //源对象键 //构造源对象属性 CopySourceStruct copySource = new CopySourceStruct(sourceAppid, sourceBucket, sourceRegion, sourceKey); // 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer string bucket = "examplebucket-1250000000"; string key = "exampleobject"; //对象键 CopyObjectRequest request = new CopyObjectRequest(bucket, key); //设置拷贝源 request.SetCopySource(copySource); //设置是否拷贝还是更新,此处是拷贝 request.SetCopyMetaDataDirective(COSXML.Common.CosMetaDataDirective.Replaced); // 替换元数据 request.SetRequestHeader("Content-Disposition", "attachment; filename=example.jpg"); //执行请求 CopyObjectResult result = cosXml.CopyObject(request); //请求成功 Console.WriteLine(result.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { Console.WriteLine("CosClientException: " + clientEx); } catch (COSXML.CosException.CosServerException serverEx) { Console.WriteLine("CosServerException: " + serverEx.GetInfo()); } }

修改对象元数据

public void CopyChangeMata() { try { // 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer string bucket = "examplebucket-1250000000"; string key = "exampleobject"; //对象键 string appId = "1250000000"; //账号 appid string region = "COS_REGION"; //源对象的存储桶所在的地域 //构造对象属性 CopySourceStruct copySource = new CopySourceStruct(appId, bucket, region, key);
//构造请求 CopyObjectRequest request = new CopyObjectRequest(bucket, key); //设置拷贝源 request.SetCopySource(copySource); //设置是否拷贝还是更新,此处是拷贝 request.SetCopyMetaDataDirective(COSXML.Common.CosMetaDataDirective.Replaced); // 替换元数据 request.SetRequestHeader("Content-Disposition", "attachment; filename=example.jpg"); request.SetRequestHeader("Content-Type", "image/png"); //执行请求 CopyObjectResult result = cosXml.CopyObject(request); //请求成功 Console.WriteLine(result.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { Console.WriteLine("CosClientException: " + clientEx); } catch (COSXML.CosException.CosServerException serverEx) { Console.WriteLine("CosServerException: " + serverEx.GetInfo()); } }

移动对象

移动对象主要包括两个操作:复制源对象到目标位置,删除源对象。
由于 COS 通过存储桶名称(Bucket)和对象键(ObjectKey)来标识对象。移动对象也就意味着修改这个对象的标识,COS .NET SDK 目前没有提供修改对象唯一标识名的单独接口,但是可以通过组合复制对象加上删除对象的基本操作,来达到修改对象标识的目的,从而实现移动对象。
例如将 sourcebucket-1250000000 这个存储桶中的 picture.jpg 这个对象移动到同个存储桶的 dir 路径下。首先可以复制 picture.jpg 对象到存储桶的 dir 路径下,即对象键设定为 dir/picture.jpg,复制完成后删除 picture.jpg 这个对象,来实现“移动”的效果。
public async Task MoveObject() { TransferConfig transferConfig = new TransferConfig(); // 初始化 TransferManager TransferManager transferManager = new TransferManager(cosXml, transferConfig); string sourceAppid = "1250000000"; //账号 appid string sourceBucket = "sourcebucket-1250000000"; //源对象所在的存储桶 string sourceRegion = "COS_REGION"; //源对象的存储桶所在的地域 string sourceKey = "picture.jpg"; //源对象键 //构造源对象属性 CopySourceStruct copySource = new CopySourceStruct(sourceAppid, sourceBucket, sourceRegion, sourceKey); string bucket = "examplebucket-1250000000"; //目标存储桶,格式:BucketName-APPID string key = "dir/picture.jpg"; //目标对象的对象键 COSXMLCopyTask copyTask = new COSXMLCopyTask(bucket, key, copySource); try { // 拷贝对象 COSXML.Transfer.COSXMLCopyTask.CopyTaskResult result = await transferManager.CopyAsync(copyTask); Console.WriteLine(result.GetResultInfo()); // 删除对象 DeleteObjectRequest request = new DeleteObjectRequest(sourceBucket, sourceKey); DeleteObjectResult deleteResult = cosXml.DeleteObject(request); // 打印结果 Console.WriteLine(deleteResult.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { Console.WriteLine("CosClientException: " + clientEx); } catch (COSXML.CosException.CosServerException serverEx) { Console.WriteLine("CosServerException: " + serverEx.GetInfo()); } }

分块操作

这里主要介绍分块复制的流程。需要注意,COS API 接口提供了 InitiateMultipartUpload、UploadPart/UploadPartCopy、CompleteMultipartUpload 一套接口可用于实现分块复制。因此分块上传和分块复制在涉及接口及使用上具有一定重合度。
分块复制的流程
1. 初始化分块(Initiate Multipart Upload),得到 UploadId。
2. 使用 UploadId 复制分块(Upload Part - Copy)。
3. 完成分块复制(Complete Multipart Upload)。
剩余分块复制的流程
1. 如果没有记录 UploadId,查询分块任务(List Multipart Uploads),得到对应文件的 UploadId。
2. 使用 UploadId 列出已复制的分块(List Parts)。
3. 使用 UploadId 复制剩余的分块(Upload Part Copy)。
4. 完成分块复制(Complete Multipart Upload)。
终止分块复制的流程
1. 如果没有记录 UploadId,查询分块复制任务(List Multipart Uploads),得到对应文件的 UploadId。
2. 终止分块复制并删除已复制分块(Abort Multipart Upload)。

查询分块复制

查询指定存储桶中正在进行的分块复制(List Multipart Uploads)。
public void ListMultipartUploads() { try { // 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer string bucket = "examplebucket-1250000000"; ListMultiUploadsRequest request = new ListMultiUploadsRequest(bucket); //执行请求 ListMultiUploadsResult result = cosXml.ListMultiUploads(request); //请求成功 Console.WriteLine(result.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { Console.WriteLine("CosClientException: " + clientEx); } catch (COSXML.CosException.CosServerException serverEx) { Console.WriteLine("CosServerException: " + serverEx.GetInfo()); } }

初始化分块复制

初始化 Multipart Upload 复制操作,获取对应的 uploadId(Initiate Multipart Upload)。
public void InitiateMultipartUpload() { try { // 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer string bucket = "examplebucket-1250000000"; string key = "exampleobject"; //对象键 InitMultipartUploadRequest request = new InitMultipartUploadRequest(bucket, key); //执行请求 InitMultipartUploadResult result = cosXml.InitMultipartUpload(request); //请求成功 this.uploadId = result.initMultipartUpload.uploadId; //用于后续分块的 uploadId Console.WriteLine(result.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { Console.WriteLine("CosClientException: " + clientEx); } catch (COSXML.CosException.CosServerException serverEx) { Console.WriteLine("CosServerException: " + serverEx.GetInfo()); } }

分块复制

将其他对象复制为一个分块 (Upload Part - Copy)。
public void UploadPartCopy() { try { string sourceAppid = "1250000000"; //账号 appid string sourceBucket = "sourcebucket-1250000000"; //"源对象所在的存储桶 string sourceRegion = "COS_REGION"; //源对象的存储桶所在的地域 string sourceKey = "sourceObject"; //源对象键 //构造源对象属性 COSXML.Model.Tag.CopySourceStruct copySource = new CopySourceStruct(sourceAppid, sourceBucket, sourceRegion, sourceKey); // 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer string bucket = "examplebucket-1250000000"; string key = "exampleobject"; //对象键 string uploadId = this.uploadId; //初始化分块上传/复制返回的uploadId int partNumber = 1; //分块编号,必须从1开始递增 UploadPartCopyRequest request = new UploadPartCopyRequest(bucket, key, partNumber, uploadId); //设置拷贝源 request.SetCopySource(copySource); //设置复制分块(指定块的范围,如 0 ~ 1M) request.SetCopyRange(0, 1024 * 1024); //执行请求 UploadPartCopyResult result = cosXml.PartCopy(request); //请求成功,获取返回分块的eTag,用于后续CompleteMultiUploads this.eTag = result.copyPart.eTag; Console.WriteLine(result.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { Console.WriteLine("CosClientException: " + clientEx); } catch (COSXML.CosException.CosServerException serverEx) { Console.WriteLine("CosServerException: " + serverEx.GetInfo()); } }

查询已复制的分块

查询特定分块复制操作中的已复制的块(List Parts)。
public void ListParts() { try { // 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer string bucket = "examplebucket-1250000000"; string key = "exampleobject"; //对象键 string uploadId = "exampleUploadId"; //初始化分块上传/复制返回的uploadId ListPartsRequest request = new ListPartsRequest(bucket, key, uploadId); //执行请求 ListPartsResult result = cosXml.ListParts(request); //请求成功,列举已上传/复制的分块 List<COSXML.Model.Tag.ListParts.Part> alreadyUploadParts = result.listParts.parts; Console.WriteLine(result.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { Console.WriteLine("CosClientException: " + clientEx); } catch (COSXML.CosException.CosServerException serverEx) { Console.WriteLine("CosServerException: " + serverEx.GetInfo()); } }


完成分块复制

完成整个文件的分块复制(Complete Multipart Upload)。
public void CompleteMultipartUpload() { try { // 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer string bucket = "examplebucket-1250000000"; string key = "exampleobject"; //对象键 string uploadId = "exampleUploadId"; //初始化分块/复制返回的uploadId CompleteMultipartUploadRequest request = new CompleteMultipartUploadRequest(bucket, key, uploadId); //设置已/复制的parts,必须有序,按照partNumber递增 request.SetPartNumberAndETag(1, this.eTag); //执行请求 CompleteMultipartUploadResult result = cosXml.CompleteMultiUpload(request); //请求成功 Console.WriteLine(result.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { Console.WriteLine("CosClientException: " + clientEx); } catch (COSXML.CosException.CosServerException serverEx) { Console.WriteLine("CosServerException: " + serverEx.GetInfo()); } }

终止分块复制

终止一个分块复制操作并删除已复制的块(Abort Multipart Upload)。
public void AbortMultipartUpload() { try { // 存储桶名称,此处填入格式必须为 bucketname-APPID, 其中 APPID 获取参考 https://console.cloud.tencent.com/developer string bucket = "examplebucket-1250000000"; string key = "exampleobject"; //对象键 string uploadId = "exampleUploadId"; //初始化分返回的uploadId AbortMultipartUploadRequest request = new AbortMultipartUploadRequest(bucket, key, uploadId); //执行请求 AbortMultipartUploadResult result = cosXml.AbortMultiUpload(request); //请求成功 Console.WriteLine(result.GetResultInfo()); } catch (COSXML.CosException.CosClientException clientEx) { Console.WriteLine("CosClientException: " + clientEx); } catch (COSXML.CosException.CosServerException serverEx) { Console.WriteLine("CosServerException: " + serverEx.GetInfo()); } }

API 操作

关于简单操作的 API 接口说明,请参见 PUT Object - Copy 文档。