Go实战--golang上传文件到七牛云对象存储(github.com/qiniu/api.
生命不止,继续 go go go !!! 在国内,七牛绝对是golang的领导者。 七牛云关于七牛: 官网: 接下来开始七牛之旅: 注册 验证 支付宝验证 添加资源(对象存储): Go SDK关于对象存储,七牛云提供了Golang版本的SDK。 文档地址 简介 Go SDK 属于七牛服务端SDK之一,主要有如下功能: 提供生成客户端上传所需的上传凭证的功能 获取 go get -u github.com/qiniu/api.v7
获取的时候出现错误: # cd D:go_workspacesrcgolang.orgxnet; 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 客户端上传凭证 这里的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,则服务端根据内容自动确定 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"`
}
指定凭证有效时间 putPolicy.Expires = 3600 //1小时有效期
这里的时间单位是秒。 构建配置类 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
表单上传的额外可选项 type PutExtra struct {
// 可选,用户自定义参数,必须以 "x:" 开头。若不以x:开头,则忽略。
Params map[string]string
// 可选,当为 "" 时候,服务端自动判断。
MimeType string
// 上传事件:进度通知。这个事件的回调函数应该尽可能快地结束。
OnProgress func(fsize,uploaded int64)
}
标准的上传回复内容 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,}
}
以表单方式上传一个文件 func (p *FormUploader) PutFile(
ctx context.Context,ret interface{},uptoken,key,localFile string,extra *PutExtra) (err error) {
return p.putFile(ctx,ret,true,localFile,extra)
}
各个参数: 实战文件上传(表单方式)直接上代码了,要把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,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,&putExtra)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(ret.Key,ret.Hash)
}
输出: 覆盖七牛云上已经存在的文件我们想替换七牛云上1.png文件,我们重新选一个本地文件命名为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),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",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)"}`,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",&putExtra)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(ret)
}
输出: 字节数组上传(表单方式)这里用到的Put而不是PutFile。 Put 用来以表单方式上传一个文件。 func (p *FormUploader) Put(
ctx context.Context,key string,data io.Reader,size int64,extra *PutExtra) (err error) {
err = p.put(ctx,data,size,extra,path.Base(key))
return
}
各个参数含义: 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,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(),bytes.NewReader(data),dataLen,&putExtra)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(ret)
}
输出: 断点续传断点续传,官方给出了完整了例子,这里就不贴代码了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |