拷贝Object
更新时间:2024-01-31
拷贝Object
简单拷贝Object
-
基本流程
- 创建BosClient。
- 执行copyObject( )方法。
-
示例代码
let options = { 'Content-Length': <file.size>, // 添加http header 'Content-Type': 'application/json', // 添加http header 'Cache-Control': 'public, max-age=31536000', // 指定缓存指令 'Content-Disposition': 'attachment; filename="example.jpg"', // 指示回复的内容该以何种形式展示 'x-bce-meta-foo1': 'bar1', // 覆盖自定义meta信息 'x-bce-meta-foo2': 'bar2', // 覆盖自定义meta信息 'x-bce-meta-foo3': 'bar3' // 覆盖自定义meta信息 } //SrcBucketName, SrcKey为Bucket/Object,DestBucketName, DestKey为拷贝到的目的Bucket/Object client.copyObject(<SrcBucketName>, <SrcKey>, <DestBucketName>, <DestKey>, options);
同步Copy功能
当前BOS的CopyObject接口是通过同步方式实现的。同步方式下,BOS端会等待Copy实际完成才返回成功。同步Copy能帮助用户更准确的判断Copy状态,但用户感知的复制时间会变长,且复制时间和文件大小成正比。
同步Copy方式更符合业界常规,提升了与其它平台的兼容性。同步Copy方式还简化了BOS服务端的业务逻辑,提高了服务效率。
Object设置meta信息
可以通过拷贝Object的方式设置meta信息。
BOS修改Object的Metadata通过拷贝Object实现。即拷贝Object的时候,把目的Bucket设置为源Bucket,目的Object设置为源Object,并设置新的Metadata,通过拷贝自身实现修改Metadata的目的。如果不设置新的Metadata,则报错。
-
示例代码
let options = {<meta_key>: <meta_value>} // SrcBucketName, SrcKey为Bucket/Object // DestBucketName = SrcBucketName, DestKey = SrcKey 目标与原Bucket/Object相同 client.copyObject(<SrcBucketName>, <SrcKey>, <DestBucketName>, <DestKey>, options);
分块拷贝
除了通过CopyObject接⼝拷贝文件以外,BOS还提供了另外一种拷贝模式——Multipart Upload Copy。用户可以在如下的应用场景内(但不仅限于此),使用Multipart Upload Copy,如:
- 需要支持断点拷贝。
- 拷贝超过5GB大小的文件。
- 网络条件较差,和BOS的服务器之间的连接经常断开。
下面将介绍分步实现三步拷贝。
三步拷贝包含init、“拷贝分块”和complete三步,其中init和complete的操作同分块上传一致。
为了便于理解,下面提供三步拷贝完整代码:
// 准备
let options = {
'Content-Length': <file.size>, // 添加http header
'Content-Type': 'application/json', // 添加http header
'Cache-Control': 'public, max-age=31536000', // 指定缓存指令
'Content-Disposition': 'attachment; filename="example.jpg"', // 指示回复的内容该以何种形式展示
'x-bce-meta-foo1': 'bar1', // 添加自定义meta信息
'x-bce-meta-foo2': 'bar2', // 添加自定义meta信息
'x-bce-meta-foo3': 'bar3' // 添加自定义meta信息
};
let PART_SIZE = 5 * 1024 * 1024; // 指定分块大小
/** 第一步 init **/
// SrcBucketName, SrcKey为原Bucket/Object
// DestBucketName, DestKey为拷贝到的目的Bucket/Object
client.initiateMultipartUpload(srcBucketName, SrcKey)
.then(function(response) {
uploadId = response.body.uploadId; // 获取服务器生成的uploadId标识任务
})
/** 第二步 分块拷贝 **/
// 获取文件大小
let leftSize = 0;
client.getObjectMetadata(<SrcBucketName>, <SrcKey>).then(response => {
leftSize = response.http_headers?.['content-length']
});
let tasks = [];
let offset = 0;
let partNumber = 1;
while (leftSize > 0) {
let partSize = Math.min(leftSize, PART_SIZE);
tasks.push({
file: <SrcKey>,
bucketName: <SrcBucketName>,
uploadId: uploadId,
partNumber: partNumber,
partSize: partSize,
start: offset,
stop: offset + partSize - 1
})
leftSize -= partSize;
offset += partSize;
partNumber+=1;
}
let partList = [];
Promise.all(tasks.map(async (task, index) => {
return client.uploadPartCopy(<SrcBucketName>, <SrcKey>, <DestBucketName>, <DestKey>,uploadId, partNumber, range, <options>).then(response => {
// do something
})
})).then(response => {
partList = response
.map(res => ({partNumber: res.partNumber, eTag: res.http_headers.eTag}));
});
/** 第三步 complete **/
client.completeMultipartUpload(<DestBucketName>, <DestKey>, uploadId, partList)
注意:
- offset参数以字节为单位,为分块的开始偏移位置。
- size参数以字节为单位,定义每个分块的大小,除最后一个Part以外,其他的Part大小都要大于 5MB。