OSS提供的分片上传(Multipart Upload)功能,将要上传的较大文件(Object)分成多个分片(Part)来分别上传,上传完成后再调用CompleteMultipartUpload接口将这些Part组合成一个Object。
注意事项
关于OSS支持的Region与Endpoint的对应关系,请参见OSS地域和访问域名。
要分片上传,您必须有
oss:PutObject
权限。具体操作,请参见为RAM用户授权自定义的权限策略。
分片上传流程
分片上传(Multipart Upload)分为以下三个步骤:
初始化一个分片上传事件。
调用client.initiateMultipartUpload方法返回OSS创建的全局唯一的uploadID。
上传分片。
调用client.uploadPart方法上传分片数据。
对于同一个uploadID,分片号(partNumber)标识了该分片在整个文件内的相对位置。如果使用同一个分片号上传了新的数据,那么OSS上该分片已有的数据将会被覆盖。
OSS将收到的分片数据的MD5值放在ETag头内返回给用户。
OSS计算上传数据的MD5值,并与SDK计算的MD5值比较,如果不一致则返回InvalidDigest错误码。
完成分片上传。
所有分片上传完成后,调用client.completeMultipartUpload方法将所有分片合并成完整的文件。
示例代码
以下代码展示如何将本地的大文件分割成多个分片文件并发上传到存储空间,然后合并成完整的文件对象。
import Client, { FilePath, RequestError, THarmonyEmptyBodyApiRes } from '@aliyun/oss';
import { fileIo as fs } from '@kit.CoreFileKit';
// 创建OSS客户端实例
const client = new Client({
// 请替换为STS临时访问凭证的Access Key ID
accessKeyId: 'yourAccessKeyId',
// 请替换为STS临时访问凭证的Access Key Secret
accessKeySecret: 'yourAccessKeySecret',
// 请替换为STS临时访问凭证的Security Token
securityToken: 'yourSecurityToken',
// 填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou
region: 'oss-cn-hangzhou',
});
// 指定要操作的Bucket名称,请替换为您实际使用的Bucket名称
const bucket = 'yourBucketName';
// 指定要上传的对象(文件)名称,请替换为您实际要上传的对象名称
const key = 'yourObjectName';
/**
* 分片上传文件到OSS。
* 使用分片上传(Multipart Upload)将大文件分成多个部分上传到指定的Bucket和Key。
*/
const multipartUpload = async () => {
try {
// 初始化分片上传任务,获取uploadId
const initRes = await client.initiateMultipartUpload({
bucket, // Bucket名称
key, // 对象(文件)名称
});
// 获取初始化返回的uploadId,用于后续分片上传和完成上传
const uploadId = initRes.data.uploadId;
// 指定本地文件路径
const filePath = new FilePath('yourFilePath');// 请替换为实际的本地文件路径
// 获取文件的元信息(如文件大小)
const fileStat = await fs.stat(filePath.filePath);
// 定义每个分片的大小(10MB)
const chunkSize = 1024 * 1024 * 10;
// 计算总分片数
let totalParts = Math.ceil(fileStat.size / chunkSize);
// 当前分片编号
let partNumber = 1;
// 存储所有分片上传的Promise对象
const waitList: Promise<THarmonyEmptyBodyApiRes>[] = [];
// 循环处理每个分片
while (partNumber <= totalParts) {
// 计算当前分片的起始位置
const offset = (partNumber - 1) * chunkSize;
// 调用uploadPart方法上传当前分片
const uploadPromise = client.uploadPart({
bucket, // Bucket名称
key, // 对象(文件)名称
uploadId, // 初始化返回的uploadId
partNumber, // 当前分片编号
data: filePath, // 文件路径
length: Math.min(chunkSize, fileStat.size - offset), // 当前分片的大小
offset, // 当前分片的起始偏移量
});
// 将分片上传的Promise添加到等待列表
waitList.push(uploadPromise);
// 增加分片编号
partNumber++;
}
// 等待所有分片上传完成
const uploadResList = await Promise.all(waitList);
// 当所有分片上传完成后,调用completeMultipartUpload完成上传任务
const completeRes = await client.completeMultipartUpload({
bucket, // Bucket名称
key, // 对象(文件)名称
uploadId, // 初始化返回的uploadId
completeAll: true, // 自动完成所有分片
});
// 打印完成分片上传的结果
console.log(JSON.stringify(completeRes));
} catch (err) {
// 捕获请求过程中的异常信息
if (err instanceof RequestError) {
// 如果是已知类型的错误,则打印错误代码、错误消息、请求ID、状态码、EC码等信息
console.log('code: ', err.code); // 错误代码
console.log('message: ', err.message); // 错误消息
console.log('requestId: ', err.requestId); // 请求ID
console.log('status: ', err.status); // HTTP状态码
console.log('ec: ', err.ec); // 错误码
} else {
// 打印其他未知类型的错误
console.log('unknown error: ', err);
}
}
};
// 调用multipartUpload函数执行分片上传操作
multipartUpload();
常见使用场景
该文章对您有帮助吗?
- 本页导读 (1)
- 注意事项
- 分片上传流程
- 示例代码
- 常见使用场景
- 取消指定的分片上传事件
- 列举指定的分片上传事件中已经成功上传的分片
- 列举执行中的分片上传事件