前期准备
开始操作前,确保您已经完成了 SDK 初始化。如果您还没有初始化 SDK,请先参考快速入门文档完成。
Go SDK 通过
transfer 包提供文件上传和下载功能,使用前需要导入相关包:import "cnb.cool/tencent/cloud/smh/smh-go-sdk/transfer"
上传文件
本文介绍如何通过 SMH Go SDK 进行文件上传,包括从本地文件上传、从 Reader 上传、秒传检测、取消上传等功能。Go SDK 支持简单上传和分块上传两种模式,根据文件大小自动选择上传方式。
功能特性
简单上传 - 适用于小文件的直接上传
分块上传 - 大文件自动分块并发上传,提升上传速度
秒传功能 - 文件 hash 匹配时直接完成上传,无需重新上传
进度监控 - 通过回调函数实时获取上传进度
取消上传 - 通过 context 取消上传任务
快速开始
ctx := context.Background()options := &transfer.UploadOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/path/to/remote/file.txt",LocalPath: "/path/to/local/file.txt",AccessToken: "your-access-token",ChunkSize: 10, // 10MB 分块大小PartFileSize: 50, // 超过 50MB 的文件使用分块上传Parallel: 5, // 5 个并发上传OnProgress: func(progress float64) {fmt.Printf("Upload progress: %.2f%%\\n", progress)},}result, err := transfer.UploadFileFromPath(ctx, transfer.LocalFileOptions{}, options, configuration)if err != nil {panic(err)}fmt.Printf("Upload completed: Name=%s, Inode=%s, Size=%s\\n",result.Name, result.Inode, result.Size)
参数说明
UploadFileFromPath 方法签名:
func UploadFileFromPath(ctx context.Context, file LocalFileOptions, options *UploadOptions, configuration *client.Configuration) (*UploadResult, error)
LocalFileOptions 结构体
参数名 | 类型 | 必填 | 说明 |
Name | string | 否 | 文件名,不指定则使用本地文件名 |
Size | int64 | 否 | 文件大小,不指定则自动获取 |
Path | string | 否 | 本地文件路径,也可通过 options.LocalPath 指定 |
Type | string | 否 | 文件 MIME 类型 |
UploadOptions 结构体
参数名 | 类型 | 必填 | 说明 |
LibraryID | string | 是 | 媒体库 ID |
SpaceID | string | 是 | 空间 ID |
FilePath | string | 是 | 远端文件路径 |
LocalPath | string | 是 | 本地文件路径 |
AccessToken | string | 是 | 访问令牌 |
UserID | string | 否 | 用户身份识别,当访问令牌对应的权限为管理员权限且申请访问令牌时的用户身份识别为空时用来临时指定用户身份 |
ChunkSize | int64 | 否 | 分块大小,单位:MB,默认值:1MB |
Parallel | int | 否 | 并发上传数,默认值:5 |
PartFileSize | int64 | 否 | 分块上传阈值,单位:MB,超过此大小的文件使用分块上传,默认值:32MB,范围:1MB - 5GB |
ConflictResolutionStrategy | string | 否 | 冲突解决策略,默认值:rename |
EnableInstantUpload | bool | 否 | 是否启用秒传功能,默认值:false |
TrafficLimit | int64 | 否 | 上传限速,单位:字节/秒 |
PreferSameOrigin | bool | 否 | 是否优先使用同源上传,默认值:false |
Labels | []string | 否 | 文件标签列表 |
Category | string | 否 | 文件自定义的分类 |
LocalCreationTime | *time.Time | 否 | 文件对应的本地创建时间 |
LocalModificationTime | *time.Time | 否 | 文件对应的本地修改时间 |
OnProgress | func(progress float64) | 否 | 进度回调函数,参数为上传进度百分比(0-100) |
UploadResult 结构体
上传成功后返回的结果结构体,包含上传文件的详细信息。
字段 | 类型 | 说明 |
Path | []string | 最终文件路径,数组中最后一个元素代表最终文件名,其他元素代表每一级目录名 |
Name | string | 最终文件名(冲突策略为 rename 时可能与请求的文件名不同) |
Type | string | 文件类型 |
Inode | string | 文件 ID,可用于后续文件操作 |
Size | string | 文件大小,字符串格式 |
Crc64 | string | 文件 CRC64-ECMA182 校验值,字符串格式 |
ETag | string | 文件 ETag |
CreationTime | *time.Time | 文件首次完成上传的时间 |
ModificationTime | *time.Time | 文件最近一次被覆盖的时间 |
ContentType | string | 媒体类型 |
IsOverwritten | bool | 文件上传时是否发生文件覆盖 |
FileType | string | 文件类型分类(如 excel、powerpoint 等) |
MetaData | map[string]string | 元数据键值对 |
上传模式
Go SDK 提供两种文件上传入口:UploadFileFromPath(从本地文件路径上传)和 UploadFileFromReader(从内存流上传)。两种方式均支持简单上传和分块上传,SDK 根据文件大小自动选择上传模式,无需手动切换。
UploadFileFromPath — 从路径上传
UploadFileFromPath 通过指定本地文件路径进行上传,是最常用的上传方式。SDK 会根据文件大小自动选择简单上传或分块上传模式:简单上传
适用于小文件(文件大小小于
PartFileSize,默认 32MB),SDK 自动使用简单上传模式,一次请求完成上传。ctx := context.Background()options := &transfer.UploadOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/uploads/small-file.txt",LocalPath: "/path/to/local/small-file.txt",AccessToken: "your-access-token",}result, err := transfer.UploadFileFromPath(ctx, transfer.LocalFileOptions{}, options, configuration)if err != nil {panic(err)}
分块上传
适用于大文件(文件大小超过
PartFileSize),SDK 自动将文件分块并发上传,单个分块失败会自动重试(含上传地址过期自动续期),局部网络抖动不会导致整个文件重新上传。ctx := context.Background()options := &transfer.UploadOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/uploads/large-video.mp4",LocalPath: "/path/to/local/large-video.mp4",AccessToken: "your-access-token",ChunkSize: 5, // 每个分块 5MBParallel: 3, // 同时上传 3 个分块PartFileSize: 32, // 超过 32MB 使用分块上传OnProgress: func(progress float64) {fmt.Printf("Upload progress: %.2f%%\\n", progress)},}result, err := transfer.UploadFileFromPath(ctx, transfer.LocalFileOptions{}, options, configuration)if err != nil {panic(err)}
UploadFileFromReader — 从内存上传
UploadFileFromReader 适用于需要从内存或数据流中直接上传的场景,如处理生成的内容、网络流数据等,无需先将数据写入本地文件。该方法同样支持简单上传和分块上传,SDK 根据数据大小自动选择。UploadFileFromReader 方法签名:
func UploadFileFromReader(ctx context.Context, file ReaderFileOptions, options *UploadOptions, configuration *client.Configuration) (*UploadResult, error)
ReaderFileOptions 结构体
Name | string | 是 | 文件名 |
Size | int64 | 否 | 文件大小,不指定则自动计算 |
Type | string | 否 | 文件 MIME 类型 |
Reader | io.Reader | 是 | 文件数据读取器 |
ctx := context.Background()content := []byte("Hello, World!")reader := bytes.NewReader(content)file := transfer.ReaderFileOptions{Name: "hello.txt",Size: int64(len(content)),Type: "text/plain",Reader: reader,}options := &transfer.UploadOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/path/to/hello.txt",AccessToken: "your-access-token",OnProgress: func(progress float64) {fmt.Printf("Upload progress: %.2f%%\\n", progress)},}result, err := transfer.UploadFileFromReader(ctx, file, options, configuration)if err != nil {panic(err)}fmt.Printf("Upload completed: Name=%s, Inode=%s\\n", result.Name, result.Inode)
秒传功能
秒传功能可以大幅提升上传效率,当后端检测到文件已存在时,直接返回成功,无需重新上传。
SDK 会自动计算文件的哈希值,服务端匹配后确认文件已存在即可完成秒传。文件大小需 ≥ 1MB 才会触发秒传检测。
ctx := context.Background()options := &transfer.UploadOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/uploads/existing-file.txt",LocalPath: "/path/to/local/existing-file.txt",AccessToken: "your-access-token",EnableInstantUpload: true, // 启用秒传}result, err := transfer.UploadFileFromPath(ctx, transfer.LocalFileOptions{}, options, configuration)if err != nil {panic(err)}// 秒传命中时上传立即完成,UploadResult 结构与正常上传一致fmt.Printf("上传完成: Name=%s, Inode=%s, ETag=%s\\n", result.Name, result.Inode, result.ETag)
取消上传
通过 Go 的
context.Context 机制取消上传任务。使用 context.WithCancel 创建可取消的 context,调用 cancel() 函数即可取消上传。ctx, cancel := context.WithCancel(context.Background())options := &transfer.UploadOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/uploads/large-video.mp4",LocalPath: "/path/to/local/large-video.mp4",AccessToken: "your-access-token",OnProgress: func(progress float64) {fmt.Printf("Upload progress: %.2f%%\\n", progress)// 在 20% 时取消上传if progress >= 20 {cancel()}},}result, err := transfer.UploadFileFromPath(ctx, transfer.LocalFileOptions{}, options, configuration)if err != nil {if errors.Is(err, context.Canceled) {fmt.Println("上传已取消")} else {panic(err)}}
下载文件
本文介绍如何通过 SMH Go SDK 进行文件下载,包括下载到本地路径、下载到内存、分块下载、取消下载等功能。Go SDK 支持简单下载和分块下载两种模式,根据文件大小自动选择下载方式。
功能特性
下载到本地路径 - 支持简单下载和分块下载,自动选择下载方式
下载到内存 - 适用于需要直接处理文件内容的场景
分块下载 - 大文件自动分块并发下载,提升下载速度
进度监控 - 通过回调函数实时获取下载进度
取消下载 - 通过 context 取消下载任务
快速开始
ctx := context.Background()options := &transfer.DownloadOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/path/to/remote/file.txt",LocalPath: "/path/to/local/file.txt",AccessToken: "your-access-token",ChunkSize: 10, // 10MB 分块大小PartFileSize: 50, // 超过 50MB 的文件使用分块下载Parallel: 5, // 5 个并发下载OnProgress: func(progress float64) {fmt.Printf("Download progress: %.2f%%\\n", progress)},}err := transfer.DownloadFileToPath(ctx, options, configuration)if err != nil {panic(err)}
参数说明
DownloadFileToPath 方法签名:
func DownloadFileToPath(ctx context.Context, options *DownloadOptions, configuration *client.Configuration) error
DownloadOptions 结构体
参数名 | 类型 | 必填 | 说明 |
LibraryID | string | 是 | 媒体库 ID |
SpaceID | string | 是 | 空间 ID |
FilePath | string | 是 | 远程文件路径 |
LocalPath | string | 是 | 本地保存路径 |
AccessToken | string | 是 | 访问令牌 |
UserID | string | 否 | 用户身份识别,当访问令牌对应的权限为管理员权限且申请访问令牌时的用户身份识别为空时用来临时指定用户身份 |
ChunkSize | int64 | 否 | 分块大小,单位:MB,默认值:1MB |
Parallel | int | 否 | 并发下载数,默认值:5 |
PartFileSize | int64 | 否 | 分块下载阈值,单位:MB,超过此大小的文件使用分块下载,默认值:32MB |
TrafficLimit | int64 | 否 | 下载限速,单位:字节/秒 |
OnProgress | func(progress float64) | 否 | 进度回调函数,参数为下载进度百分比(0-100) |
使用 DownloadFileToMemory 直接获取内容
适用于需要直接处理文件内容的场景,如读取配置文件、处理小型文档等。
DownloadFileToMemory 方法签名:
func DownloadFileToMemory(ctx context.Context, options *DownloadToMemoryOptions, configuration *client.Configuration) ([]byte, error)
DownloadToMemoryOptions 结构体
参数名 | 类型 | 必填 | 说明 |
LibraryID | string | 是 | 媒体库 ID |
SpaceID | string | 是 | 空间 ID |
FilePath | string | 是 | 远程文件路径 |
AccessToken | string | 是 | 访问令牌 |
UserID | string | 否 | 用户身份识别,当访问令牌对应的权限为管理员权限且申请访问令牌时的用户身份识别为空时用来临时指定用户身份 |
MaxSize | int64 | 否 | 最大允许下载大小,单位:字节,默认值:100MB,防止内存溢出 |
TrafficLimit | int64 | 否 | 下载限速,单位:字节/秒 |
OnProgress | func(progress float64) | 否 | 进度回调函数,参数为下载进度百分比(0-100) |
ctx := context.Background()options := &transfer.DownloadToMemoryOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/path/to/config.json",AccessToken: "your-access-token",OnProgress: func(progress float64) {fmt.Printf("Download progress: %.2f%%\\n", progress)},}data, err := transfer.DownloadFileToMemory(ctx, options, configuration)if err != nil {panic(err)}fmt.Printf("Downloaded %d bytes\\n", len(data))fmt.Printf("Content: %s\\n", string(data))
下载模式
SDK 根据文件大小自动选择下载模式,无需手动切换。
1. 简单下载
适用于小文件(小于
PartFileSize,默认 32MB),使用单个请求完成下载。ctx := context.Background()options := &transfer.DownloadOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/downloads/small-file.txt",LocalPath: "/path/to/local/small-file.txt",AccessToken: "your-access-token",}err := transfer.DownloadFileToPath(ctx, options, configuration)if err != nil {panic(err)}
2. 分块下载
适用于大文件(大于
PartFileSize),自动分块并发下载。每个分块使用 HTTP Range 请求下载,下载完成后自动合并为完整文件。ctx := context.Background()options := &transfer.DownloadOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/downloads/large-video.mp4",LocalPath: "/path/to/local/large-video.mp4",AccessToken: "your-access-token",ChunkSize: 5, // 每个分块 5MBParallel: 3, // 同时下载 3 个分块PartFileSize: 32, // 超过 32MB 使用分块下载OnProgress: func(progress float64) {fmt.Printf("Download progress: %.2f%%\\n", progress)},}err := transfer.DownloadFileToPath(ctx, options, configuration)if err != nil {panic(err)}
取消下载
通过 Go 的
context.Context 机制取消下载任务。使用 context.WithCancel 创建可取消的 context,调用 cancel() 函数即可取消下载。ctx, cancel := context.WithCancel(context.Background())options := &transfer.DownloadOptions{LibraryID: "your-library-id",SpaceID: "your-space-id",FilePath: "/downloads/large-video.mp4",LocalPath: "/path/to/local/large-video.mp4",AccessToken: "your-access-token",OnProgress: func(progress float64) {fmt.Printf("Download progress: %.2f%%\\n", progress)// 在 20% 时取消下载if progress >= 20 {cancel()}},}err := transfer.DownloadFileToPath(ctx, options, configuration)if err != nil {if errors.Is(err, context.Canceled) {fmt.Println("下载已取消")} else {panic(err)}}