全部產品
Search
文件中心

Object Storage Service:分區上傳(Harmony SDK)

更新時間:Dec 18, 2025

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();