Harmony分片上传

更新时间:2025-03-10 10:31:15

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

注意事项

分片上传流程

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

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

    调用client.initiateMultipartUpload方法返回OSS创建的全局唯一的uploadID。

  2. 上传分片。

    调用client.uploadPart方法上传分片数据。

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

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

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

  3. 完成分片上传。

    所有分片上传完成后,调用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();

常见使用场景

取消指定的分片上传事件

您可以使用client.abortMultipartUpload方法取消分片上传事件。

import Client, { RequestError } from '@aliyun/oss';

// 创建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';

/**
 * 中止分片上传任务。
 * 使用abortMultipartUpload方法中止指定的分片上传任务。
 */
const abortMultipartUpload = async () => {
  try {
    // 调用abortMultipartUpload方法中止指定的分片上传任务
    const res = await client.abortMultipartUpload({
      bucket, // Bucket名称
      key,    // 对象(文件)名称
      // uploadId可以从client.initiateMultipartUpload或client.listMultipartUploads的返回结果中获取
      uploadId: 'uploadId', // 请替换为实际的uploadId
    });

    // 打印中止分片上传的结果
    console.log(JSON.stringify(res));
  } 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);
    }
  }
};

// 调用abortMultipartUpload函数执行中止分片上传操作
abortMultipartUpload();

列举指定的分片上传事件中已经成功上传的分片

您可以使用client.listParts方法列举指定的分片上传事件中已经成功上传的分片。

import Client, { RequestError } from '@aliyun/oss';

// 创建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';

/**
 * 列出已上传的分片。
 * 使用listParts方法列出指定分片上传任务中已上传的分片信息。
 */
const listParts = async () => {
  try {
    // 调用listParts方法列出指定分片上传任务中已上传的分片信息
    const res = await client.listParts({
      bucket, // Bucket名称
      key,    // 对象(文件)名称
      // uploadId可以从client.initiateMultipartUpload或client.listMultipartUploads的返回结果中获取
      uploadId: 'uploadId', // 请替换为实际的uploadId
    });

    // 打印已上传分片的信息
    console.log(JSON.stringify(res));
  } 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);
    }
  }
};

// 调用listParts函数执行列出已上传分片的操作
listParts();

列举执行中的分片上传事件

您可以使用client.listMultipartUploads方法列举已经初始化但还未完成(Complete)或者还未中止(Abort)的分片上传事件。

import Client, { RequestError } from '@aliyun/oss';

// 创建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';

/**
 * 列出执行中且未完成的分片上传任务。
 * 使用listMultipartUploads方法列出指定Bucket中未完成的分片上传任务。
 */
const listMultipartUploads = async () => {
  try {
    // 调用listMultipartUploads方法列出指定Bucket中未完成的分片上传任务
    const res = await client.listMultipartUploads({
      bucket, // Bucket名称
    });

    // 打印未完成分片上传任务的信息
    console.log(JSON.stringify(res));
  } 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);
    }
  }
};

// 调用listMultipartUploads函数执行列出未完成分片上传任务的操作
listMultipartUploads();
  • 本页导读 (1)
  • 注意事项
  • 分片上传流程
  • 示例代码
  • 常见使用场景
  • 取消指定的分片上传事件
  • 列举指定的分片上传事件中已经成功上传的分片
  • 列举执行中的分片上传事件
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等