复制对象
CopyObject操作用于创建一个已经在媒体存储中的对象。使用CopyOoject可以复制单个最大为5GB的对象,如果需要复制更大的对象,可以使用UploadPartCopy操作。执行CopyObject操作,必须具有对被拷贝对象的READ权限和对目标bucket的WRITE权限。
拷贝生成的对象默认保留原对象的元数据信息,也可以才CopyObject操作中指定新的元数据。拷贝生成的对象不会保留原来的ACL信息,该对象默认是发起CopyObject操作的用户私有的。
CopyObject操作默认拷贝原对象的当前版本数据,如果需要拷贝原对象的指定版本,可以在CopySource中加入versionId来拷贝指定的Object版本,如果原对象的versionId为删除标记,则不会被拷贝。
示例代码:
using System;
using System.Threading.Tasks;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;
namespace DotNetSDK.ObjectOperation
{
public class CopyObjectExample
{
public static async Task CopyObject()
{
var accessKey = "YOUR_ACCESS_KEY";
var secretKey = "YOUR_SECRET_KEY";
var endpoint = "YOUR_ENDPOINT";
var sourceBucket = "SOURCE_BUCKET";
var sourceKey = "SOURCE_KEY";
var destinationBucket = "DESTINATION_BUCKET";
var destinationKey = "DESTINATION_KEY";
try
{
var credentials = new BasicAWSCredentials(accessKey, secretKey);
var conf = new AmazonS3Config
{
ServiceURL = endpoint
};
var s3Client = new AmazonS3Client(credentials, conf);
var copyObjectRequest = new CopyObjectRequest()
{
SourceBucket = sourceBucket,
SourceKey = sourceKey,
DestinationBucket = destinationBucket,
DestinationKey = destinationKey
};
var result = await s3Client.CopyObjectAsync(copyObjectRequest);
if (result.HttpStatusCode != System.Net.HttpStatusCode.OK)
{
Console.WriteLine("fail to copy object, HttpStatusCode:{0}, ErrorCode:{1}.", (int) result.HttpStatusCode, result.HttpStatusCode);
return;
}
Console.WriteLine("copy object from {0}/{1} to {2}/{3}.", sourceBucket, sourceKey, destinationBucket, destinationKey);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
CopyObjectRequest可设置的参数如下:
参数 | 类型 | 说明 | 是否必要 |
---|---|---|---|
CannedACL | S3CannedACL | 拷贝后对象的预定义的标准ACL信息。 | 否 |
DestinationBucket | string | 放置拷贝生成对象的bucket的名称。 | 是 |
DestinationKey | string | 拷贝生成对象的key。 | 是 |
SourceBucket | string | 放置被拷贝对象的bucket的名称。 | 是 |
SourceKey | string | 被拷贝对象的key。 | 是 |
Metadata | MetadataCollection | 拷贝生成对象的元数据信息。 | 否 |
MetadataDirective | S3MetadataDirective | 指定拷贝生成的对象的元数据信息来自被拷贝对象,还是来自请求中附带的信息。 | 否 |
TagSet | List<Tag> | 拷贝生成对象的标签信息。 | 否 |
SourceVersionId | string | 指定被拷贝对象的版本信息,如果不指定,默认拷贝对象的当前版本。 | 否 |
WebsiteRedirectLocation | string | 如果bucket被配置用于提供网站的静态数据,该参数可以用于设置访问对象时候重定向到当前bucket下的其他对象或者外部的URL。 | 否 |
CopyObject返回的结果如下:
参数 | 类型 | 说明 |
---|---|---|
ETag | string | 拷贝生成对象的ETag。 |
LastModified | string | 拷贝生成对象的最新修改时间。 |
响应结果:
HTTP状态码 | 响应码 | 描述 |
---|---|---|
200 | OK | 操作成功。 |
400 | BadRequest | 拷贝的对象太大或者对象的名字不合法。 |
403 | Forbidden | 用户没有权限执行操作。 |
404 | NotFound | 设置的bucket或者对象key不存在。 |
CopyPart操作可以从一个已存在的对象中拷贝指定片段的数据,当拷贝的对象大小超过5GB,必须使用UploadPartCopy操作完成对象的复制。除了最后一个片段外,每个拷贝片段的大小范围是[5MB,5GB]。在一个在拷贝大对象之前,需要使用CompleteMultiPartUpload操作获取一个upload ID,在完成拷贝操作之后,需要使用CompleteMultipartUpload操作组装已拷贝的片段成为一个对象。
代码示例:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;
namespace DotNetSDK.ObjectOperation
{
public class CopyPartsExample
{
public static async Task CopyParts()
{
var accessKey = "YOUR_ACCESS_KEY";
var secretKey = "YOUR_SECRET_KEY";
var endpoint = "YOUR_ENDPOINT";
var sourceBucket = "SOURCE_BUCKET";
var sourceKey = "SOURCE_KEY";
var destinationBucket = "DESTINATION_BUCKET";
var destinationKey = "DESTINATION_KEY";
try
{
var credentials = new BasicAWSCredentials(accessKey, secretKey);
List<CopyPartResponse> copyResponses = new List<CopyPartResponse>();
var conf = new AmazonS3Config
{
ServiceURL = endpoint
};
var s3Client = new AmazonS3Client(credentials, conf);
// 发起一个分段上传操作请求,获取upload id
Task<InitiateMultipartUploadResponse> taskInitiateMultipartUploadResp = s3Client.InitiateMultipartUploadAsync(new InitiateMultipartUploadRequest()
{
BucketName = destinationBucket,
Key = destinationKey
});
var uploadId = taskInitiateMultipartUploadResp.Result.UploadId;
Console.WriteLine("upload id: {0}", uploadId);
// 获取被拷贝对象的大小
GetObjectMetadataRequest getObjectMetadataRequest = new GetObjectMetadataRequest
{
BucketName = sourceBucket,
Key = sourceKey
};
var getObjectMetadataResponse = await s3Client.GetObjectMetadataAsync(getObjectMetadataRequest);
long objectSize = getObjectMetadataResponse.ContentLength;
// 拷贝分段
long partSize = 5 * (long) Math.Pow(2, 20); // 5 MB.
long bytePosition = 0;
for (int i = 1; bytePosition < objectSize; i++)
{
CopyPartRequest copyPartRequest = new CopyPartRequest
{
DestinationBucket = destinationBucket,
DestinationKey = destinationKey,
SourceBucket = sourceBucket,
SourceKey = sourceKey,
UploadId = uploadId,
FirstByte = bytePosition,
LastByte = bytePosition + partSize - 1 >= objectSize ? objectSize - 1 : bytePosition + partSize - 1,
PartNumber = i
};
var copyPartResponse = await s3Client.CopyPartAsync(copyPartRequest);
copyResponses.Add(copyPartResponse);
bytePosition += partSize;
}
// 完成拷贝分段
CompleteMultipartUploadRequest completeRequest =
new CompleteMultipartUploadRequest
{
BucketName = destinationBucket,
Key = destinationKey,
UploadId = uploadId
};
completeRequest.AddPartETags(copyResponses);
CompleteMultipartUploadResponse completeUploadResponse = await s3Client.CompleteMultipartUploadAsync(completeRequest);
if (completeUploadResponse.HttpStatusCode != System.Net.HttpStatusCode.OK)
{
Console.WriteLine("fail to get copy parts, HttpStatusCode:{0}, ErrorCode:{1}.", (int) completeUploadResponse.HttpStatusCode, completeUploadResponse.HttpStatusCode);
return;
}
Console.WriteLine("copy object from {0}/{1} to {2}/{3}.", sourceBucket, sourceKey, destinationBucket, destinationKey);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
CopyPartRequest可设置的参数如下:
参数 | 类型 | 说明 | 是否必要 |
---|---|---|---|
DestinationBucket | string | 放置拷贝生成对象的bucket的名称。 | 是 |
DestinationKey | string | 拷贝生成对象的key。 | 是 |
SourceBucket | string | 放置被拷贝对象的bucket的名称。 | 是 |
SourceKey | string | 被拷贝对象的key。 | 是 |
UploadId | string | 与本次拷贝操作相应的分段上传Id。 | 是 |
SourceVersionId | string | 指定被拷贝对象的版本信息,如果不指定,默认拷贝对象的当前版本。 | 否 |
CopyPart返回的结果如下:
参数 | 类型 | 说明 |
---|---|---|
ContentLength | long | 拷贝片段的长度。 |
ETag | string | 拷贝片段的ETag。 |
LastModified | string | 拷贝片段的最新修改时间。 |
PartNumber | int | 拷贝片段的序号。 |
响应结果:
HTTP状态码 | 响应码 | 描述 |
---|---|---|
200 | OK | 操作成功。 |
400 | BadRequest | 拷贝的对象太大或者对象的名字不合法。 |
403 | Forbidden | 用户没有权限执行操作。 |
404 | NotFound | 设置的bucket或者对象key不存在。 |