You need to enable JavaScript to run this app.
导航

分片拷贝(Node.js SDK)

最近更新时间2024.02.04 18:31:05

首次发布时间2023.07.04 15:29:43

对象大于 5GiB 时,需要使用 uploadPartCopy 来进行分片拷贝。

注意事项

  • 拷贝文件不支持跨区域的桶间拷贝。
  • 拷贝对象时,账号必须具备源对象的读取权限和目标桶的写入权限。
  • 拷贝对象时,可以保留所有元数据(默认值)或指定新的元数据。但 ACL 并未被保留,而是设置为私有。

分片拷贝步骤

  1. 通过 createMultipartUpload 初始化分片拷贝任务。
  2. 通过 uploadPartCopy 进行分片拷贝。
  3. 通过 completeMultipartUpload 合并分片。

示例代码

// 导入 SDK, 当 TOS Node.JS SDK 版本小于 2.5.2 请把下方 TosClient 改成 TOS 导入
import { TosClient, TosClientError, TosServerError } from '@volcengine/tos-sdk';

// 创建客户端
const client = new TosClient({
  accessKeyId: process.env['TOS_ACCESS_KEY'], 
  accessKeySecret: process.env['TOS_SECRET_KEY'], 
  region: "Provide your region", // 填写 Bucket 所在地域。以华北2(北京)为例,"Provide your region" 填写为 cn-beijing。
  endpoint: "Provide your endpoint", // 填写域名地址
});

function handleError(error) {
  if (error instanceof TosClientError) {
    console.log('Client Err Msg:', error.message);
    console.log('Client Err Stack:', error.stack);
  } else if (error instanceof TosServerError) {
    console.log('Request ID:', error.requestId);
    console.log('Response Status Code:', error.statusCode);
    console.log('Response Header:', error.headers);
    console.log('Response Err Code:', error.code);
    console.log('Response Err Msg:', error.message);
  } else {
    console.log('unexpected exception, message: ', error);
  }
}

async function main() {
  try {
    const srcBucket = 'node-sdk-test-bucket'; // 源桶
    const srcObject = 'example_dir/multipartExample'; // 源对象
    const dstBucket = 'node-sdk-copy-bucket'; // 目标桶
    const dstObject = 'example_dir/multipartExample-copy'; // 目标对象

    // 获取上传任务 ID
    const {
      data: { UploadId },
    } = await client.createMultipartUpload({
      bucket: dstBucket,
      key: dstObject,
    });
    console.log('UploadId', UploadId);

    // 获取桶源桶中已存在对象的大小
    const {
      data: { 'content-length': contentLength },
    } = await client.headObject({
      bucket: srcBucket,
      key: srcObject,
    });
    console.log('srcObject content-length', contentLength);
    // 文件总大小
    const totalSize = contentLength;

    const partSize = 5 * 1024 * 1024;

    let offset = 0;
    let partNumber = 1;
    const partsInfo = [];

    while (offset < totalSize) {
      // 上传分片拷贝
      const uploadResult = await client.uploadPartCopy({
        bucket: dstBucket,
        key: dstObject,
        partNumber,
        uploadId: UploadId,
        headers: {
          'x-tos-copy-source': `/${srcBucket}/${srcObject}`,
          'x-tos-copy-source-range': `bytes=${offset}-${offset + partSize}`,
        },
      });
      const eTag = uploadResult.data.ETag;
      console.log(`partNumber${partNumber} Etag:`, eTag);
      partsInfo.push({
        partNumber,
        eTag,
      });
      partNumber++;
      offset += partSize;
    }
    console.log('parts information', partsInfo);

    // 完成分片上传
    const { data } = await client.completeMultipartUpload({
      bucket: dstBucket,
      key: dstObject,
      uploadId: UploadId,
      parts: partsInfo,
    });

    console.log('result data:', data);
  } catch (error) {
    handleError(error);
  }
}
main();

相关文档