Go实战--golang上传文件到七牛云对象存储(github.com/qiniu/api.v7)
2017-10-18 13:36
369 查看
生命不止,继续 go go go !!!
在国内,七牛绝对是golang的领导者。
(七牛云)隶属于上海七牛信息技术有限公司,七牛云是国内领先的企业级云服务商,专注于以数据管理为中心的云计算业务研发和运营,围绕富媒体场景推出了对象存储、融合 CDN 加速、容器计算云、大数据平台、人工智能平台等产品,并提供一站式视频云解决方案。公司目前已位列国内云计算行业第一阵营,为 70 多万家企业提供服务。
官网:
https://www.qiniu.com
接下来开始七牛之旅:
注册
验证
支付宝验证
添加资源(对象存储):
输入存储空间名称,也就是bucket
选择存储区域,有华东、华北、华南、北美
选择访问控制,有公开空间和私有空间选择
文档地址
https://developer.qiniu.com/kodo/sdk/1238/go
简介
此 SDK 适用于 Go 1.7.0 及以上版本。使用此 SDK 构建您的网络应用程序,能让您以非常便捷的方式将数据安全地存储到七牛云上。无论您的网络应用是一个网站程序,还是包括从云端(服务端程序)到终端(手持设备应用)的架构服务和应用,通过七牛云及其 SDK,都能让您应用程序的终端用户高速上传和下载,同时也让您的服务端更加轻盈。
Go SDK 属于七牛服务端SDK之一,主要有如下功能:
提供生成客户端上传所需的上传凭证的功能
提供文件从服务端直接上传七牛的功能
提供对七牛空间中文件进行管理的功能
提供对七牛空间中文件进行处理的功能
提供七牛CDN相关的刷新,预取,日志功能
获取
获取的时候出现错误:
原因呢,你懂的,自己想办法解决~~~
这里跟大家分享的,主要是客户端上传。
服务端SDK在上传方面主要提供两种功能,一种是生成客户端上传所需要的上传凭证,另外一种是直接上传文件到云端。
在七牛云的控制面板中, 个人中心,密钥管理中可以查看自己的*Access Key 和 Secret Key。
客户端上传凭证
客户端(移动端或者Web端)上传文件的时候,需要从客户自己的业务服务器获取上传凭证,而这些上传凭证是通过服务端的SDK来生成的,然后通过客户自己的业务API分发给客户端使用。根据上传的业务需求不同,七牛云 Go SDK支持丰富的上传凭证生成方式。
这里的bucket即你在七牛云设置的存储空间名称,accessKey, secretKey即上面提到的。
表示文件上传的上传策略
指定凭证有效时间
默认情况下,在不指定上传凭证的有效时间情况下,默认有效期为1个小时。也可以自行指定上传凭证的有效期:
这里的时间单位是秒。
构建配置类
七牛存储支持空间创建在不同的机房,在使用七牛的 Go SDK 中的FormUploader和ResumeUploader上传文件之前,必须要构建一个上传用的Config对象,在该对象中,可以指定空间对应的zone以及其他的一些影响上传的参数。
Config 为文件上传,资源管理等配置
我们可以这么写:
这里需要注意的是cfg.Zone,还记得之前添加资源的时候,选择的区域吗?
表单上传的额外可选项
// PutExtra 为表单上传的额外可选项
标准的上传回复内容
如果使用了上传回调或者自定义了returnBody,那么需要根据实际情况,自己自定义一个返回值结构体
表单上传的对象
FormUploader 表示一个表单上传的对象
构建一个表单上传的对象
以表单方式上传一个文件
PutFile 用来以表单方式上传一个文件,和 Put 不同的只是一个通过提供文件路径来访问文件内容,一个通过 io.Reader 来访问。
各个参数:
ctx 是请求的上下文。
ret 是上传成功后返回的数据。如果 uptoken 中没有设置 callbackUrl 或 returnBody,那么返回的数据结构是 PutRet 结构。
uptoken 是由业务服务器颁发的上传凭证。
key 是要上传的文件访问路径。比如:”foo/bar.jpg”。注意我们建议 key 不要以 ‘/’ 开头。另外,key 为空字符串是合法的。
localFile 是要上传的文件的本地路径。
extra 是上传的一些可选项,可以指定为nil。详细见 PutExtra 结构的描述。
输出:
1.png FhR37vPVvgaAKJl56iaR5nLip-jM
登录七牛云,在内容管理中可以看到我们上传的文件
file exists
那我们应该如何覆盖?
其实,很简单,我们要知道想要覆盖的文件名称,这里就是1.png
我们可以看到,文件已经被覆盖。
输出:
Put 用来以表单方式上传一个文件。
各个参数含义:
ctx 是请求的上下文。
ret 是上传成功后返回的数据。如果 uptoken 中没有设置 callbackUrl 或 returnBody,那么返回的数据结构是 PutRet 结构。
uptoken 是由业务服务器颁发的上传凭证。
key 是要上传的文件访问路径。比如:”foo/bar.jpg”。注意我们建议 key 不要以 ‘/’ 开头。另外,key 为空字符串是合法的。
data 是文件内容的访问接口(io.Reader)。
fsize 是要上传的文件大小。
extra 是上传的一些可选项。可以指定为nil。详细见 PutExtra 结构的描述。
输出:
{2.log Fh3tNUEoiaj-qkNcP915nRuiAm4- 0 }
在国内,七牛绝对是golang的领导者。
七牛云
关于七牛:(七牛云)隶属于上海七牛信息技术有限公司,七牛云是国内领先的企业级云服务商,专注于以数据管理为中心的云计算业务研发和运营,围绕富媒体场景推出了对象存储、融合 CDN 加速、容器计算云、大数据平台、人工智能平台等产品,并提供一站式视频云解决方案。公司目前已位列国内云计算行业第一阵营,为 70 多万家企业提供服务。
官网:
https://www.qiniu.com
接下来开始七牛之旅:
注册
验证
支付宝验证
添加资源(对象存储):
输入存储空间名称,也就是bucket
选择存储区域,有华东、华北、华南、北美
选择访问控制,有公开空间和私有空间选择
Go SDK
关于对象存储,七牛云提供了Golang版本的SDK。文档地址
https://developer.qiniu.com/kodo/sdk/1238/go
简介
此 SDK 适用于 Go 1.7.0 及以上版本。使用此 SDK 构建您的网络应用程序,能让您以非常便捷的方式将数据安全地存储到七牛云上。无论您的网络应用是一个网站程序,还是包括从云端(服务端程序)到终端(手持设备应用)的架构服务和应用,通过七牛云及其 SDK,都能让您应用程序的终端用户高速上传和下载,同时也让您的服务端更加轻盈。
Go SDK 属于七牛服务端SDK之一,主要有如下功能:
提供生成客户端上传所需的上传凭证的功能
提供文件从服务端直接上传七牛的功能
提供对七牛空间中文件进行管理的功能
提供对七牛空间中文件进行处理的功能
提供七牛CDN相关的刷新,预取,日志功能
获取
go get -u github.com/qiniu/api.v7
获取的时候出现错误:
# cd D:\go_workspace\src\golang.org\x\net; git pull --ff-only fatal: unable to access 'https://go.googlesource.com/net/': Failed to connect to go.googlesource.com port 443: Timed out package golang.org/x/net/context: exit status 1
原因呢,你懂的,自己想办法解决~~~
上传文件
七牛文件上传分为客户端上传(主要是指网页端和移动端等面向终端用户的场景)和服务端上传两种场景,具体可以参考文档七牛业务流程。这里跟大家分享的,主要是客户端上传。
服务端SDK在上传方面主要提供两种功能,一种是生成客户端上传所需要的上传凭证,另外一种是直接上传文件到云端。
相关知识介绍
Access Key 和 Secret Key在七牛云的控制面板中, 个人中心,密钥管理中可以查看自己的*Access Key 和 Secret Key。
客户端上传凭证
客户端(移动端或者Web端)上传文件的时候,需要从客户自己的业务服务器获取上传凭证,而这些上传凭证是通过服务端的SDK来生成的,然后通过客户自己的业务API分发给客户端使用。根据上传的业务需求不同,七牛云 Go SDK支持丰富的上传凭证生成方式。
这里的bucket即你在七牛云设置的存储空间名称,accessKey, secretKey即上面提到的。
putPolicy := storage.PutPolicy{ Scope: bucket, } mac := qbox.NewMac(accessKey, secretKey) upToken := putPolicy.UploadToken(mac)
表示文件上传的上传策略
type PutPolicy struct { Scope string `json:"scope"` Expires uint32 `json:"deadline"` // 截止时间(以秒为单位) IsPrefixalScope int `json:"isPrefixalScope,omitempty"` InsertOnly uint16 `json:"insertOnly,omitempty"` // 若非0, 即使Scope为 Bucket:Key 的形式也是insert only DetectMime uint8 `json:"detectMime,omitempty"` // 若非0, 则服务端根据内容自动确定 MimeType FsizeLimit int64 `json:"fsizeLimit,omitempty"` MimeLimit string `json:"mimeLimit,omitempty"` SaveKey string `json:"saveKey,omitempty"` CallbackFetchKey uint8 `json:"callbackFetchKey,omitempty"` CallbackURL string `json:"callbackUrl,omitempty"` CallbackHost string `json:"callbackHost,omitempty"` CallbackBody string `json:"callbackBody,omitempty"` CallbackBodyType string `json:"callbackBodyType,omitempty"` ReturnURL string `json:"returnUrl,omitempty"` ReturnBody string `json:"returnBody,omitempty"` PersistentOps string `json:"persistentOps,omitempty"` PersistentNotifyURL string `json:"persistentNotifyUrl,omitempty"` PersistentPipeline string `json:"persistentPipeline,omitempty"` EndUser string `json:"endUser,omitempty"` DeleteAfterDays int `json:"deleteAfterDays,omitempty"` FileType int `json:"fileType,omitempty"` }
指定凭证有效时间
默认情况下,在不指定上传凭证的有效时间情况下,默认有效期为1个小时。也可以自行指定上传凭证的有效期:
putPolicy.Expires = 3600 //1小时有效期
这里的时间单位是秒。
构建配置类
七牛存储支持空间创建在不同的机房,在使用七牛的 Go SDK 中的FormUploader和ResumeUploader上传文件之前,必须要构建一个上传用的Config对象,在该对象中,可以指定空间对应的zone以及其他的一些影响上传的参数。
Config 为文件上传,资源管理等配置
type Config struct { Zone *Zone //空间所在的机房 UseHTTPS bool //是否使用https域名 UseCdnDomains bool //是否使用cdn加速域名 }
我们可以这么写:
cfg := storage.Config{} // 空间对应的机房 cfg.Zone = &storage.ZoneHuadong // 是否使用https域名 cfg.UseHTTPS = false // 上传是否使用CDN上传加速 cfg.UseCdnDomains = false
这里需要注意的是cfg.Zone,还记得之前添加资源的时候,选择的区域吗?
华东 storage.ZoneHuadong 华北 storage.ZoneHuabei 华南 storage.ZoneHuanan 北美 storage.ZoneBeimei
表单上传的额外可选项
// PutExtra 为表单上传的额外可选项
type PutExtra struct { // 可选,用户自定义参数,必须以 "x:" 开头。若不以x:开头,则忽略。 Params map[string]string // 可选,当为 "" 时候,服务端自动判断。 MimeType string // 上传事件:进度通知。这个事件的回调函数应该尽可能快地结束。 OnProgress func(fsize, uploaded int64) }
标准的上传回复内容
如果使用了上传回调或者自定义了returnBody,那么需要根据实际情况,自己自定义一个返回值结构体
type PutRet struct { Hash string `json:"hash"` PersistentID string `json:"persistentId"` Key string `json:"key"` }
表单上传的对象
FormUploader 表示一个表单上传的对象
type FormUploader struct { client *rpc.Client cfg *Config }
构建一个表单上传的对象
func NewFormUploader(cfg *Config) *FormUploader { if cfg == nil { cfg = &Config{} } return &FormUploader{ client: &rpc.DefaultClient, cfg: cfg, } }
以表单方式上传一个文件
PutFile 用来以表单方式上传一个文件,和 Put 不同的只是一个通过提供文件路径来访问文件内容,一个通过 io.Reader 来访问。
func (p *FormUploader) PutFile( ctx context.Context, ret interface{}, uptoken, key, localFile string, extra *PutExtra) (err error) { return p.putFile(ctx, ret, uptoken, key, true, localFile, extra) }
各个参数:
ctx 是请求的上下文。
ret 是上传成功后返回的数据。如果 uptoken 中没有设置 callbackUrl 或 returnBody,那么返回的数据结构是 PutRet 结构。
uptoken 是由业务服务器颁发的上传凭证。
key 是要上传的文件访问路径。比如:”foo/bar.jpg”。注意我们建议 key 不要以 ‘/’ 开头。另外,key 为空字符串是合法的。
localFile 是要上传的文件的本地路径。
extra 是上传的一些可选项,可以指定为nil。详细见 PutExtra 结构的描述。
实战
文件上传(表单方式)
直接上代码了,要把accessKey和secretKey换成你自己的!!!!package main import ( "context" "fmt" "github.com/qiniu/api.v7/auth/qbox" "github.com/qiniu/api.v7/storage" ) func main() { accessKey := "TgVGKnpCMLDI6hSS4rSWE3g-FZjMPf6Zbc******" secretKey := "zqZvH3fNVaggw00oc9wCrcWKgeeiV7WITF******" localFile := "1.png" bucket := "wangshubotest" key := "1.png" putPolicy := storage.PutPolicy{ Scope: bucket, } mac := qbox.NewMac(accessKey, secretKey) upToken := putPolicy.UploadToken(mac) cfg := storage.Config{} cfg.Zone = &storage.ZoneHuadong cfg.UseHTTPS = false cfg.UseCdnDomains = false formUploader := storage.NewFormUploader(&cfg) ret := storage.PutRet{} putExtra := storage.PutExtra{ Params: map[string]string{ "x:name": "github logo", }, } err := formUploader.PutFile(context.Background(), &ret, upToken, key, localFile, &putExtra) if err != nil { fmt.Println(err) return } fmt.Println(ret.Key, ret.Hash) }
输出:
1.png FhR37vPVvgaAKJl56iaR5nLip-jM
登录七牛云,在内容管理中可以看到我们上传的文件
覆盖七牛云上已经存在的文件
我们想替换七牛云上1.png文件,我们重新选一个本地文件命名为1.png,然后执行上面的代码,结果输出:file exists
那我们应该如何覆盖?
其实,很简单,我们要知道想要覆盖的文件名称,这里就是1.png
package main import ( "context" "fmt" "github.com/qiniu/api.v7/auth/qbox" "github.com/qiniu/api.v7/storage" ) func main() { accessKey := "TgVGKnpCMLDI6hSS4rSWE3g-FZjMPf6Zbc******" secretKey := "zqZvH3fNVaggw00oc9wCrcWKgeeiV7WITF******" localFile := "1.png" bucket := "wangshubotest" key := "1.png" keyToOverwrite := "1.png" putPolicy := storage.PutPolicy{ Scope: fmt.Sprintf("%s:%s", bucket, keyToOverwrite), } mac := qbox.NewMac(accessKey, secretKey) upToken := putPolicy.UploadToken(mac) cfg := storage.Config{} // 空间对应的机房 cfg.Zone = &storage.ZoneHuadong // 是否使用https域名 cfg.UseHTTPS = false // 上传是否使用CDN上传加速 cfg.UseCdnDomains = false // 构建表单上传的对象 formUploader := storage.NewFormUploader(&cfg) ret := storage.PutRet{} // 可选配置 putExtra := storage.PutExtra{ Params: map[string]string{ "x:name": "github logo", }, } err := formUploader.PutFile(context.Background(), &ret, upToken, key, localFile, &putExtra) if err != nil { fmt.Println(err) return } fmt.Println(ret.Key, ret.Hash) }
我们可以看到,文件已经被覆盖。
上传文件自定义返回值结构体
之前的两段代码,上传文件的返回都是key和hash,我们是可以自己定义的,主要是设置ReturnBody:package main import ( "context" "fmt" "github.com/qiniu/api.v7/auth/qbox" "github.com/qiniu/api.v7/storage" ) // 自定义返回值结构体 type MyPutRet struct { Key string Hash string Fsize int Bucket string Name string } func main() { accessKey := "TgVGKnpCMLDI6hSS4rSWE3g-FZjMPf6Zbc******" secretKey := "zqZvH3fNVaggw00oc9wCrcWKgeeiV7WITF******" localFile := "1.png" bucket := "wangshubotest" key := "1.png" putPolicy := storage.PutPolicy{ Scope: bucket, ReturnBody: `{"key":"$(key)","hash":"$(etag)","fsize":$(fsize),"bucket":"$(bucket)","name":"$(x:name)"}`, } mac := qbox.NewMac(accessKey, secretKey) upToken := putPolicy.UploadToken(mac) cfg := storage.Config{} // 空间对应的机房 cfg.Zone = &storage.ZoneHuadong // 是否使用https域名 cfg.UseHTTPS = false // 上传是否使用CDN上传加速 cfg.UseCdnDomains = false // 构建表单上传的对象 formUploader := storage.NewFormUploader(&cfg) ret := MyPutRet{} // 可选配置 putExtra := storage.PutExtra{ Params: map[string]string{ "x:name": "github logo", }, } err := formUploader.PutFile(context.Background(), &ret, upToken, key, localFile, &putExtra) if err != nil { fmt.Println(err) return } fmt.Println(ret) }
输出:
{1.png Fn616MXMfraD1V_u_TKIjC3X491Z 28540 wangshubotest github logo}
字节数组上传(表单方式)
这里用到的Put而不是PutFile。Put 用来以表单方式上传一个文件。
func (p *FormUploader) Put( ctx context.Context, ret interface{}, uptoken, key string, data io.Reader, size int64, extra *PutExtra) (err error) { err = p.put(ctx, ret, uptoken, key, true, data, size, extra, path.Base(key)) return }
各个参数含义:
ctx 是请求的上下文。
ret 是上传成功后返回的数据。如果 uptoken 中没有设置 callbackUrl 或 returnBody,那么返回的数据结构是 PutRet 结构。
uptoken 是由业务服务器颁发的上传凭证。
key 是要上传的文件访问路径。比如:”foo/bar.jpg”。注意我们建议 key 不要以 ‘/’ 开头。另外,key 为空字符串是合法的。
data 是文件内容的访问接口(io.Reader)。
fsize 是要上传的文件大小。
extra 是上传的一些可选项。可以指定为nil。详细见 PutExtra 结构的描述。
package main import ( "bytes" "context" "fmt" "github.com/qiniu/api.v7/auth/qbox" "github.com/qiniu/api.v7/storage" ) // 自定义返回值结构体 type MyPutRet struct { Key string Hash string Fsize int Bucket string Name string } func main() { accessKey := "TgVGKnpCMLDI6hSS4rSWE3g-FZjMPf6Zbc******" secretKey := "zqZvH3fNVaggw00oc9wCrcWKgeeiV7WITF******" bucket := "wangshubotest" key := "2.log" putPolicy := storage.PutPolicy{ Scope: bucket, } mac := qbox.NewMac(accessKey, secretKey) upToken := putPolicy.UploadToken(mac) cfg := storage.Config{} cfg.Zone = &storage.ZoneHuadong cfg.UseHTTPS = false cfg.UseCdnDomains = false formUploader := storage.NewFormUploader(&cfg) ret := MyPutRet{} // 可选配置 putExtra := storage.PutExtra{ Params: map[string]string{ "x:name": "github logo", }, } data := []byte("welcome to the hotel") dataLen := int64(len(data)) err := formUploader.Put(context.Background(), &ret, upToken, key, bytes.NewReader(data), dataLen, &putExtra) if err != nil { fmt.Println(err) return } fmt.Println(ret) }
输出:
{2.log Fh3tNUEoiaj-qkNcP915nRuiAm4- 0 }
断点续传
断点续传,官方给出了完整了例子,这里就不贴代码了。相关文章推荐
- Go实战--golang实现静态文件服务器(文件查看,文件上传,文件下载)
- java对七牛云的简单操作(对象存储文件上传)
- Go实战--golang中读写文件的几种方式
- Go实战--golang中文件以及文件夹路径相关操作
- Go实战--golang实现MP4视频文件服务器(nareix/joy4)
- Hbuilder开发app实战-识岁04-七牛云上传文件的js实现
- Go实战--golang中读写文件的几种方式
- 彻底清除Github上某个文件的历史(针对误上传密码文件等情况)
- 上传本地文件到GitHub
- Go实战--golang中使用echo框架中的HTTP/2、Server Push(labstack/echo、golang.org/x/net/http2)
- 【SSH网上商城项目实战13】Struts2实现文件上传功能
- 如何在Github上上传本地文件
- 支持多文件、多格式远程上传的FTP实战案例
- 【Android实战】----基于Retrofit实现多图片/文件、图文上传
- github创建分支上传自己的文件代码
- github配置公钥以及文件的上传
- golang实战使用gin+xorm搭建go语言web框架restgo详解5.9 控制器controller编程示例
- 【笔记】网易微专业-Web安全工程师-04.WEB安全实战-6.文件上传
- github配置和文件上传
- 初学者上传文件到github