上传大对象时可以分成多个数据块(part)来分别上传,最后调用合并分片将上传的数据块合并为一个对象。
tos:PutObject
权限,具体操作,请参见权限配置指南。tos:AbortMultipartUpload
权限,具体操作,请参见权限配置指南。分片上传一般包含以下三个步骤:
说明
下面代码展示将本地文件通过分片的方式上传完整过程,并在上传时指定 ACL 为 Private,存储类型为低频存储以及添加自定义元数据。
// 导入 SDK, 当 TOS Node.JS SDK 版本小于 2.5.2 请把下方 TosClient 改成 TOS 导入 import { ACLType, StorageClassType, TosClient, TosClientError, TosServerError } from '@volcengine/tos-sdk'; import fs from 'fs'; import fsp from 'fs/promises'; // 创建客户端 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 bucketName = 'node-sdk-test-bucket'; const objectName = 'example_dir/multipartExample'; // 本地 example_dir 文件夹下的 multipartExample 文件 const filePath = './example_dir/multipartExample'; // 初始化分片,指定对象权限为私有,存储类型为低频并设置元数据信息 const { // 获取上传任务 ID data: { UploadId }, } = await client.createMultipartUpload({ bucket: bucketName, key: objectName, acl: ACLType.ACLPrivate, storageClass: StorageClassType.StorageClassIa, meta: { key: 'value ' }, }); console.log('CreateMultipartUploadV2 Upload ID:', UploadId); // 获取本地文件信息并准备进行分片 const stats = await fsp.stat(filePath); // 文件总大小 const totalSize = stats.size; // part size 大小设置为 5M const partSize = 5 * 1024 * 1024; let offset = 0; // partNumber 编号从 1 开始 let partNumber = 1; const partsInfo = []; while (offset < totalSize) { const uploadResult = await client.uploadPart({ bucket: bucketName, key: objectName, partNumber, uploadId: UploadId, body: fs.createReadStream(filePath, { start: offset, end: offset + partSize - 1, }), }); 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: bucketName, key: objectName, uploadId: UploadId, parts: partsInfo, }); console.log('result data:', data); } catch (error) { handleError(error); } } main();
以下代码用于列举指定存储桶中指定对象已上传的分片信息。
// 导入 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 bucketName = 'node-sdk-test-bucket'; const objectName = '*** Provide your object name ***'; // 分片上传任务 ID,可以从 createMultipartUpload 接口获取 const uploadId = '*** Provide upload ID ***'; // 列举 uploadID 已上传分片信息 for (let truncated = true, marker = 0; truncated; ) { const { data } = await client.listParts({ bucket: bucketName, key: objectName, uploadId, partNumberMarker: marker, }); truncated = data.IsTruncated; marker = data.NextPartNumberMarker; for (const part of data.Parts) { console.log(`Part Number: `, part.PartNumber); console.log(`ETag: `, part.ETag); console.log(`Size: `, part.Size); } } } catch (error) { handleError(error); } } main();
您可以通过 abortMultipartUpload 方法来取消分片上传任务。当一个分片任务被取消后, TOS 会将已上传的分片数据删除,同时您无法再对此分片任务进行任何操作。
// 导入 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", // 填写域名地址 }); async function main() { try { const bucketName = 'node-sdk-test-bucket'; const objectName = '*** Provide your object name ***'; // 分片上传任务 ID,可以从 createMultipartUpload 接口获取 const uploadId = `*** Provide upload ID ***`; // 取消分片上传任务 const { data } = await client.abortMultipartUpload({ bucket: bucketName, key: objectName, uploadId, }); console.log('result data:', data); } catch (error) { handleError(error); } } 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); } } main();