帮你快速理解、总结文档立即下载

上传与下载

最近更新时间:2026-09-30 16:51:33
我的收藏

前期准备

开始操作前,确保您已经完成了 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, // 每个分块 5MB
Parallel: 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, // 每个分块 5MB
Parallel: 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)
}
}