前期准备
开始操作前,确保您已经完成了 SDK 初始化。如果您还没有初始化 SDK,请先参考快速入门文档完成。
上传文件
本文介绍如何通过 SMH Node SDK 上传文件。SDK 提供高层封装
createUploadTask,自动完成秒传检测、分片并发、上传确认等全流程,支持进度监控、暂停/取消与断点续传。功能特性
简单上传 - 小文件一次请求完成上传
分片上传 - 大文件自动分片并发上传,提升上传速度
秒传 - 默认开启,文件 hash 匹配时直接完成上传,无需传输文件内容
断点续传 - 支持通过 checkpoint 恢复中断的上传
进度监控 - 通过事件回调实时获取上传进度与速度
任务控制 - 支持暂停、取消、等待完成
快速开始
// createUploadTask 为异步方法,返回 UploadTaskconst task = await smh.createUploadTask({filePath: '/uploads/report.pdf', // 远端保存路径localPath: '/local/path/report.pdf', // 本地文件路径});// 监听进度task.on('progress', ({ progress, speed, leftTime }) => {console.log(`进度: ${progress.toFixed(2)}%, 速度: ${speed} 字节/秒, 预计剩余: ${leftTime} 秒`);});// 开始上传并等待完成task.start();await task.wait();console.log('上传完成:', task.file);
注意:
与浏览器版 JS SDK 不同,Node SDK 的
createUploadTask/createDownloadTask 是异步方法(需读取本地文件信息),返回 Promise,需使用 await 获取任务对象后再调用 start()。参数说明
createUploadTask 方法签名:createUploadTask(options: CreateUploadTaskOptions): Promise<UploadTask>
CreateUploadTaskOptions 参数
参数名 | 参数描述 | 类型 | 是否必填 |
filePath | 远端文件路径 | String | 是 |
localPath | 本地文件路径 | String | 是 |
libraryId | 媒体库 ID,不传则使用客户端默认值 | String | 否 |
spaceId | 空间 ID,不传则使用客户端默认值 | String | 否 |
accessToken | 访问令牌,不传则使用客户端默认值 | String | 否 |
userId | 用户身份识别 | String | 否 |
chunkSize | 分片大小,单位 MB,默认 1 | Number | 否 |
parallel | 并发上传数,默认 5 | Number | 否 |
partFileSize | 分片上传阈值,单位 MB,超过此大小的文件使用分片上传,默认 32,范围 1MB-5GB | Number | 否 |
conflictResolutionStrategy | 冲突处理:ask、rename、overwrite | String | 否 |
enableInstantUpload | 是否启用秒传,默认 true | Boolean | 否 |
trafficLimit | 上传限速,单位字节/秒 | Number | 否 |
autoCreateDir | 目录不存在时自动创建(默认 false,开启后遇到 DirectoryNotFound 会自动创建目录并重试一次) | Boolean | 否 |
labels | 文件标签列表 | Array | 否 |
category | 文件自定义分类 | String | 否 |
localCreationTime | 文件对应的本地创建时间 | String | 否 |
localModificationTime | 文件对应的本地修改时间 | String | 否 |
checkpoint | Object | 否 | |
onProgress | 进度回调:onProgress(state, progress) | Function | 否 |
onStateChange | 状态变化回调:onStateChange(checkpoint, state, error) | Function | 否 |
onPartComplete | 分片完成回调:onPartComplete(checkpoint, partInfo) | Function | 否 |
onComplete | 上传完成回调:onComplete(result),result 为完成上传接口的响应 | Function | 否 |
任务控制与事件
UploadTask 提供以下方法与属性:方法/属性 | 说明 |
start() | 开始上传 |
pause() | 暂停上传 |
cancel() | 取消上传 |
wait() | 等待上传完成(Promise<void>),完成后通过 getCheckpoint() 或任务属性获取结果 |
getCheckpoint() | 获取当前检查点(用于断点续传) |
progress / loaded / speed / leftTime | 进度、已传字节、速度、预计剩余时间等属性 |
state | 当前状态(waiting/running/paused/success/rapid_success/error/canceled 等) |
事件监听(task.on):
事件 | 回调参数 | 说明 |
progress | { state, progress, loaded, total, speed, leftTime } | 上传进度(节流上报) |
statechange | { checkpoint, state, error } | 状态变化 |
partialcomplete | { checkpoint, partInfo } | 分片完成 |
const task = await smh.createUploadTask({filePath: '/uploads/large-video.mp4',localPath: '/local/path/large-video.mp4',});task.on('statechange', ({ state, error }) => {console.log('状态变化:', state, error || '');});task.on('partialcomplete', ({ partInfo }) => {console.log(`分片 ${partInfo.part_number} 上传完成`);});task.start();// 5 秒后暂停setTimeout(() => task.pause(), 5000);try {await task.wait();console.log('上传完成');} catch (e) {console.error('上传失败或已取消:', e.message);}
秒传
秒传默认开启(
enableInstantUpload 默认 true):SDK 自动计算文件哈希,服务端匹配到相同内容时直接完成上传,任务状态为 rapid_success,无需传输文件内容。const task = await smh.createUploadTask({filePath: '/uploads/existing-file.pdf',localPath: '/local/path/existing-file.pdf',});task.start();await task.wait();if (task.state === 'rapid_success') {console.log('秒传成功,文件已存在');} else {console.log('上传完成');}
断点续传
上传中断(网络故障、进程退出等)后,可通过 checkpoint 恢复:将上次任务的 checkpoint 保存下来,重新创建任务时传入即可从断点继续。
// 首次上传(被中断)const task = await smh.createUploadTask({filePath: '/uploads/large-video.mp4',localPath: '/local/path/large-video.mp4',});task.start();// ... 中断时将 task.getCheckpoint() 持久化保存(如 fs.writeFileSync('/tmp/smh-checkpoint.json', JSON.stringify(task.getCheckpoint())))// 恢复上传(从本地文件读取持久化的 checkpoint)import fs from 'fs';const savedCheckpoint = JSON.parse(fs.readFileSync('/tmp/smh-checkpoint.json', 'utf-8'));const resumeTask = await smh.createUploadTask({filePath: '/uploads/large-video.mp4',localPath: '/local/path/large-video.mp4',checkpoint: savedCheckpoint,});resumeTask.start();await resumeTask.wait();
取消上传
const task = await smh.createUploadTask({filePath: '/uploads/large-video.mp4',localPath: '/local/path/large-video.mp4',});task.start();// 需要取消时调用 cancel()setTimeout(() => task.cancel(), 5000);try {await task.wait();} catch (e) {console.log('上传已取消:', e.message);}
下载文件
本文介绍如何通过 SMH Node SDK 将文件下载到本地路径。SDK 提供高层封装
createDownloadTask,支持分片并发下载、进度监控与完整性校验。注意:
Node SDK 没有浏览器版的
downloadByUrl 方法(浏览器原生下载);Node 场景请使用 createDownloadTask 下载到本地路径,或通过 infoFile 获取带签名的下载链接(cosUrl)后自行处理。功能特性
分片下载 - 大文件自动分片并发下载,提升下载速度
完整性校验 - 下载完成后自动进行 CRC64 校验
临时文件保护 - 先下载到
本地路径 + .download.part 临时文件,校验通过后改名为目标文件已存在跳过 - 本地已存在同名文件且校验通过时直接完成
进度监控与任务控制 - 与上传一致(progress 事件、pause/cancel/wait、checkpoint 断点续传)
快速开始
const task = await smh.createDownloadTask({filePath: '/documents/report.pdf', // 远端文件路径localPath: '/local/downloads/report.pdf', // 本地保存路径});task.on('progress', ({ progress, speed, leftTime }) => {console.log(`下载进度: ${progress.toFixed(2)}%`);});task.start();await task.wait();console.log('下载完成:', task.file);
参数说明
createDownloadTask 方法签名:createDownloadTask(options: CreateDownloadTaskOptions): Promise<DownloadTask>
CreateDownloadTaskOptions 参数
参数名 | 参数描述 | 类型 | 是否必填 |
filePath | 远端文件路径 | String | 是 |
localPath | 本地保存路径 | String | 是 |
libraryId | 媒体库 ID,不传则使用客户端默认值 | String | 否 |
spaceId | 空间 ID,不传则使用客户端默认值 | String | 否 |
accessToken | 访问令牌,不传则使用客户端默认值 | String | 否 |
userId | 用户身份识别 | String | 否 |
chunkSize | 分片大小,单位 MB,默认 1 | Number | 否 |
parallel | 并发下载数,默认 5 | Number | 否 |
partFileSize | 分片下载阈值,单位 MB,默认 32 | Number | 否 |
trafficLimit | 下载限速,单位字节/秒 | Number | 否 |
historyId | 历史版本 ID,用于下载历史版本文件 | String | 否 |
internalDomain | 是否使用内网域名,0 或 1,默认 0 | Number | 否 |
checkpoint | 断点续传检查点 | Object | 否 |
onProgress | 进度回调:onProgress(state, progress) | Function | 否 |
onStateChange | 状态变化回调 | Function | 否 |
onPartComplete | 分片完成回调 | Function | 否 |
分片下载与断点续传
大文件(超过
partFileSize,默认 32MB)自动分片并发下载,每个分片使用 HTTP Range 请求,下载完成并校验通过后合并为完整文件。中断后可通过 checkpoint 恢复(用法同上传断点续传)。const task = await smh.createDownloadTask({filePath: '/videos/large-video.mp4',localPath: '/local/downloads/large-video.mp4',chunkSize: 5, // 每个分片 5MBparallel: 3, // 同时下载 3 个分片});task.on('partialcomplete', ({ partInfo }) => {console.log(`分片 ${partInfo.part_number} 下载完成`);});task.start();await task.wait();console.log('下载完成');