下载对象

最近更新时间:2024-09-14 18:11:12

我的收藏

简介

本文介绍对象存储 COS 通过 Go SDK 实现下载对象功能的示例代码和描述。包括高级接口、简单接口两个部分。

注意事项

若您想要下载对象,需要具有目标对象的读权限:在您进行 授权策略 时,action 需要设置为cos:GetObject ,更多授权请参见 支持CAM的业务接口

相关示例

功能名称
描述
示例代码
高级接口
高级接口封装了简单下载接口,支持断点下载,下载目录,但不支持流式下载。
简单接口
GET Object 接口可以实现流式下载和下载对象到本地文件,不支持断点下载功能。

高级接口(推荐)

下载对象

功能说明

分块下载接口根据用户对象的长度,自动使用 Range 下载数据,可以实现并发下载,当对象大于16MB时,采用 Range 方式下载文件,可通过 PartSize 参数调整。

方法原型

func (s *ObjectService) Download(ctx context.Context, name string, filepath string, opt *MultiDownloadOptions) (*Response, error)

请求示例

package main

import (
"context"
"github.com/tencentyun/cos-go-sdk-v5"
"net/http"
"net/url"
"os"
)

func main() {
// 存储桶名称,由 bucketname-appid 组成,appid 必须填入,可以在 COS 控制台查看存储桶名称。 https://console.cloud.tencent.com/cos5/bucket
// 替换为用户的 region,存储桶 region 可以在 COS 控制台“存储桶概览”查看 https://console.cloud.tencent.com/ ,关于地域的详情见 https://cloud.tencent.com/document/product/436/6224 。
u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
// 通过环境变量获取密钥
// 环境变量 SECRETID 表示用户的 SecretId,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
SecretID: os.Getenv("SECRETID"), // 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
// 环境变量 SECRETKEY 表示用户的 SecretKey,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
SecretKey: os.Getenv("SECRETKEY"), // 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
},
})

key := "exampleobject" // 前面不需要带斜杠/
file := "localfile"

opt := &cos.MultiDownloadOptions{
ThreadPoolSize: 5,
}
_, err := client.Object.Download(
context.Background(), key, file, opt,
)
if err != nil {
panic(err)
}
}

参数说明

type MultiDownloadOptions struct {
Opt *ObjectGetOptions
PartSize int64
ThreadPoolSize int
CheckPoint bool
CheckPointFile string
}
参数名称
参数描述
类型
是否必填
name
对象键(Key)是对象在存储桶中的唯一标识。例如,在对象的访问域名examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/doc/pic.jpg中,对象键为 doc/pic.jpg
string
filepath
本地文件名
string
opt
下载对象参数
Struct
Opt
请求参数,详情请参见 ObjectGetOptions
Struct
PartSize
块大小,单位为 MB,如果用户不指定或者指定 partSize <= 0,由 Go SDK 自动切分,新版本中默认16MB
int64
ThreadPoolSize
线程池大小,默认为1
int
CheckPoint
是否开启断点续传,默认为false
bool
CheckPointFile
开启断点续传时,表示保存下载进度的文件路径,默认路径为 <filepath>.cosresumabletask,当下载完成后,该进度文件会被清理掉
string

返回结果说明

参数名称
参数描述
类型
*Response
http 响应,通过该返回结果获取响应状态码和响应头部等信息
Struct
error
出错信息,正常返回为 nil
Struct

简单操作

功能说明

下载一个 Object(文件/对象)至本地(GET Object)。支持简单下载、批量下载操作。

方法原型

func (s *ObjectService) Get(ctx context.Context, key string, opt *ObjectGetOptions) (*Response, error)

func (s *ObjectService) GetToFile(ctx context.Context, key, localfile string, opt *ObjectGetOptions) (*Response, error)

参数说明

type ObjectGetOptions struct {
ResponseContentType string
ResponseContentLanguage string
ResponseExpires string
ResponseCacheControl string
ResponseContentDisposition string
ResponseContentEncoding string
Range string
IfModifiedSince string
XCosTrafficLimit int
Listener ProgressListener
}
参数名称
参数描述
类型
是否必填
key
对象键(Key)是对象在存储桶中的唯一标识。例如,在对象的访问域名 examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com/doc/pic.jpg 中,对象键为 doc/pic.jpg
string
localfile
对象保存至本地的文件名称
string
ResponseContentType
设置响应头部 Content-Type
string
ResponseContentLanguage
设置响应头部 Content-Language
string
ResponseExpires
设置响应头部 Content-Expires
string
ResponseCacheControl
设置响应头部 Cache-Control
string
ResponseContentDisposition
设置响应头部 Content-Disposition
string
ResponseContentEncoding
设置响应头部 Content-Encoding
string
Range
设置下载文件的范围,格式为 bytes=first-last
string
IfModifiedSince
在指定时间后被修改才返回
string
XCosTrafficLimit
设置单链接限速
int
Listener
进度回调接口
Struct

返回结果说明

{
'Body': '',
'Accept-Ranges': 'bytes',
'Content-Type': 'application/octet-stream',
'Content-Length': '16807',
'Content-Disposition': 'attachment; filename="filename.jpg"',
'Content-Range': 'bytes 0-16086/16087',
'ETag': '"9a4802d5c99dafe1c04da0a8e7e166bf"',
'Last-Modified': 'Wed, 28 Oct 2014 20:30:00 GMT',
'X-Cos-Request-Id': 'NTg3NzQ3ZmVfYmRjMzVfMzE5N182NzczMQ=='
}
通过返回结果 Response 获取。
resp, err := client.Object.Get(context.Background(), key, nil)
body, _ := io.ReadAll(resp.Body)
contentType := resp.Header.Get("Content-Type")
contentLength := resp.Header.Get("Content-Length")
etag := resp.Header.Get("ETag")
reqid := resp.Header.Get("X-Cos-Request-Id")

参数名称
参数描述
类型
Body
下载文件的内容
StreamBody
文件元信息
下载文件的元信息,包括 Etag 和 X-Cos-Request-Id 等信息,也会返回设置的文件元信息
string

使用案例:下载对象

package main

import (
"context"
"github.com/tencentyun/cos-go-sdk-v5"
"net/http"
"net/url"
"io"
"os"
)

func main() {
// 存储桶名称,由 bucketname-appid 组成,appid 必须填入,可以在 COS 控制台查看存储桶名称。 https://console.cloud.tencent.com/cos5/bucket
// 替换为用户的 region,存储桶 region 可以在 COS 控制台“存储桶概览”查看 https://console.cloud.tencent.com/ ,关于地域的详情见 https://cloud.tencent.com/document/product/436/6224 。
u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
// 通过环境变量获取密钥
// 环境变量 SECRETID 表示用户的 SecretId,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
SecretID: os.Getenv("SECRETID"), // 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
// 环境变量 SECRETKEY 表示用户的 SecretKey,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
SecretKey: os.Getenv("SECRETKEY"), // 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
},
})

key := "exampleobject" // 前面不需要带斜杠/
opt := &cos.ObjectGetOptions{
ResponseContentType: "text/html",
Range: "bytes=0-3", // 通过 range 下载0~3字节的数据
}
// opt 可选,无特殊设置可设为 nil
// 1. 从响应体中获取对象
resp, err := client.Object.Get(context.Background(), key, opt)
if err != nil {
panic(err)
}
io.ReadAll(resp.Body)
resp.Body.Close()

// 2. 下载对象到本地文件
_, err = client.Object.GetToFile(context.Background(), key, "example.txt", nil)
if err != nil {
panic(err)
}
}

使用案例:批量下载(从 COS 下载目录)

package main
import (
"context"
"fmt"
"net/http"
"net/url"
"os"
"path"
"strings"
"sync"

"github.com/tencentyun/cos-go-sdk-v5"
)

func download(wg *sync.WaitGroup, c *cos.Client, keysCh <-chan []string) {
defer wg.Done()
for keys := range keysCh {
key := keys[0]
filename := keys[1]
_, err := c.Object.GetToFile(context.Background(), key, filename, nil)
if err != nil {
fmt.Println(err)
}
}
}
func main() {
u, _ := url.Parse("https://test-1259654469.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
c := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
// os.Getenv 表示获取环境变量
SecretID: os.Getenv("SECRETID"), // 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
SecretKey: os.Getenv("SECRETKEY"), // 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
},
})
// 多线程执行
keysCh := make(chan []string, 3)
var wg sync.WaitGroup
threadpool := 3
for i := 0; i < threadpool; i++ {
wg.Add(1)
go download(&wg, c, keysCh)
}
isTruncated := true
prefix := "dir" // 下载 dir 目录下所有文件, 文件名最左侧不需要带斜杠/
marker := ""
localDir := "./local/"
for isTruncated {
opt := &cos.BucketGetOptions{
Prefix: prefix,
Marker: marker,
EncodingType: "url", // url 编码
}
// 列出目录
v, _, err := c.Bucket.Get(context.Background(), opt)
if err != nil {
fmt.Println(err)
break
}
for _, c := range v.Contents {
key, _ := cos.DecodeURIComponent(c.Key) //EncodingType: "url",先对 key 进行 url decode
localfile := localDir + key
if _, err := os.Stat(path.Dir(localfile)); err != nil && os.IsNotExist(err) {
os.MkdirAll(path.Dir(localfile), os.ModePerm)
}
// 以/结尾的key(目录文件)不需要下载
if strings.HasSuffix(localfile, "/") {
continue
}
keysCh <- []string{key, localfile}
}
marker, _ = cos.DecodeURIComponent(v.NextMarker) // EncodingType: "url",先对 NextMarker 进行 url decode
isTruncated = v.IsTruncated
}
close(keysCh)
wg.Wait()
}

使用案例:单链接限速


package main

import (
"context"
"github.com/tencentyun/cos-go-sdk-v5"
"net/http"
"net/url"
"os"
)

func main() {
// 存储桶名称,由 bucketname-appid 组成,appid 必须填入,可以在 COS 控制台查看存储桶名称。 https://console.cloud.tencent.com/cos5/bucket
// 替换为用户的 region,存储桶 region 可以在 COS 控制台“存储桶概览”查看 https://console.cloud.tencent.com/ ,关于地域的详情见 https://cloud.tencent.com/document/product/436/6224 。
u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
// 通过环境变量获取密钥
// 环境变量 SECRETID 表示用户的 SecretId,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
SecretID: os.Getenv("SECRETID"), // 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
// 环境变量 SECRETKEY 表示用户的 SecretKey,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
SecretKey: os.Getenv("SECRETKEY"), // 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
},
})

key := "exampleobject" // 前面不需要带斜杠/
opt := &cos.ObjectGetOptions{
// 限速值设置范围为819200 - 838860800,单位默认为 bit/s,即800Kb/s - 800Mb/s,如果超出该范围将返回400错误
XCosTrafficLimit: 819200,
}
// opt 可选,无特殊设置可设为 nil
// 1. 从响应体中获取对象
_, err := client.Object.GetToFile(context.Background(), key, "example.txt", opt)
if err != nil {
panic(err)
}
}

使用案例:请求获取下载进度

Go SDK 通过回调的方式获取下载进度,用户需要自行实现 cos.ProgressListener 接口,接口定义如下:
const (
// 数据开始传输
ProgressStartedEvent ProgressEventType = iota
// 数据传输中
ProgressDataEvent
// 数据传输完成, 但不能表示对应 API 调用完成
ProgressCompletedEvent
// 只有在数据传输时发生错误才会返回
ProgressFailedEvent
)
type ProgressEvent struct {
EventType ProgressEventType
RWBytes int64 // 单次读写的字节
ConsumedBytes int64 // 已完成的字节
TotalBytes int64 // 总字节
Err error // 错误
}
type ProgressListener interface {
ProgressChangedCallback(event *ProgressEvent)
}
package main

import (
"context"
"fmt"
"github.com/tencentyun/cos-go-sdk-v5"
"io"
"net/http"
"net/url"
"os"
)

type SelfListener struct {
}

// 自定义进度回调,需要实现 ProgressChangedCallback 方法
func (l *SelfListener) ProgressChangedCallback(event *cos.ProgressEvent) {
switch event.EventType {
case cos.ProgressDataEvent:
fmt.Printf("\\r[ConsumedBytes/TotalBytes: %d/%d, %d%%]",
event.ConsumedBytes, event.TotalBytes, event.ConsumedBytes*100/event.TotalBytes)
case cos.ProgressFailedEvent:
fmt.Printf("\\nTransfer Failed: %v", event.Err)
}
}
func main() {
// 存储桶名称,由 bucketname-appid 组成,appid 必须填入,可以在 COS 控制台查看存储桶名称。 https://console.cloud.tencent.com/cos5/bucket
// 替换为用户的 region,存储桶 region 可以在 COS 控制台“存储桶概览”查看 https://console.cloud.tencent.com/ ,关于地域的详情见 https://cloud.tencent.com/document/product/436/6224 。
u, _ := url.Parse("https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com")
b := &cos.BaseURL{BucketURL: u}
client := cos.NewClient(b, &http.Client{
Transport: &cos.AuthorizationTransport{
// 通过环境变量获取密钥
// 环境变量 SECRETID 表示用户的 SecretId,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
SecretID: os.Getenv("SECRETID"), // 用户的 SecretId,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
// 环境变量 SECRETKEY 表示用户的 SecretKey,登录访问管理控制台查看密钥,https://console.cloud.tencent.com/cam/capi
SecretKey: os.Getenv("SECRETKEY"), // 用户的 SecretKey,建议使用子账号密钥,授权遵循最小权限指引,降低使用风险。子账号密钥获取可参见 https://cloud.tencent.com/document/product/598/37140
},
})
key := "exampleobject" // 前面不需要带斜杠/
opt := &cos.ObjectGetOptions{
ResponseContentType: "text/html",
// 使用默认方式查看进度
Listener: &cos.DefaultProgressListener{},
}
// opt 可选,无特殊设置可设为 nil
// 1. 从响应体中获取对象
resp, err := client.Object.Get(context.Background(), key, opt)
if err != nil {
panic(err)
}
io.ReadAll(resp.Body)
resp.Body.Close()

// 2. 下载对象到本地文件
// 使用自定义的进度回调方法
opt.Listener = &SelfListener{}
_, err = client.Object.GetToFile(context.Background(), key, "example.txt", opt)
if err != nil {
panic(err)
}
}

API 操作

关于下载对象接口涉及的 API 接口说明,请参见 GET Object 查看。