Beego文件上傳至七牛雲的玩法

前言

Beego是一款GO語言開發的傳統MVC的框架,beego對上傳這塊的代碼封裝的也非常簡單易用。

beego的上傳

貼出官方的一段代碼

https://beego.me/docs/mvc/con...

func (c *FormController) Post() {
    f, h, err := c.GetFile("uploadname")
    if err != nil {
        log.Fatal("getfile err ", err)
    }
    defer f.Close()
    c.SaveToFile("uploadname", "static/upload/" + h.Filename) // 保存位置在 static/upload, 沒有文件夾要先創建
    
}

這裏beego通過 GetFile方法獲取文件的name,既設置的 input name="uploadname" 可以通過其第二個返回值獲得文件的詳細詳細

h.Filename
h.Header
h.size

上面的例子是一個傳統上傳,既將文件拷貝到本地項目目錄中。

七牛雲

關於註冊、登錄、獲取key什麼的本文就不廢話了。官方提供了Go的Sdk

文檔地址:https://developer.qiniu.com/k...

安裝

通過go get 安裝包

go get -u github.com/qiniu/api.v7

使用

這裏演示兩種上傳方式
七牛官方的SDK提供了幾個上傳方法,如下所示

// 本地文件上傳至七牛雲
func (p *FormUploader) PutFile
func (p *FormUploader) PutFileWithoutKey
// 數據流方式上傳至七牛雲
func (p *FormUploader) Put
func (p *FormUploader) PutWithoutKey

這個SDK也允許你自定義返回結果,通過重寫結構體的方式

type PutRet struct {
    Hash         string `json:"hash"`
    PersistentID string `json:"persistentId"`
    Key          string `json:"key"`
}

本地上傳

這是官方的一個demo,本地上傳這裏就不多闡述了,大概都能看懂

// 設置上傳文件
localFile = "/Users/jemy/Documents/github.png"
// 設置上傳空間名
bucket = "if-pbl"
// 上傳的文件名稱
key = "github-x.png"

putPolicy := storage.PutPolicy{
    Scope:               bucket,
}
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)

流信息上傳

這是我自行封裝的流上傳代碼

package qiniu

import (
    "github.com/qiniu/api.v7/storage"
    "github.com/qiniu/api.v7/auth/qbox"
    "context"
    "io"
)

const (
    bucket    = "avatars" // 
    accessKey = ""
    secretKey = ""
)

func config() storage.Config {
    cfg := storage.Config{}

    cfg.Zone = &storage.ZoneHuadong
    // 是否使用https域名
    cfg.UseHTTPS = false
    // 上傳是否使用CDN上傳加速
    cfg.UseCdnDomains = false

    return cfg
}

func Upload(localFile io.Reader, size int64, filename string) (string, error) {

    putPolicy := storage.PutPolicy{
        Scope: bucket,
    }

    mac := qbox.NewMac(accessKey, secretKey)
    upToken := putPolicy.UploadToken(mac)

    cig := config()

    formUploader := storage.NewFormUploader(&cig)

    ret := storage.PutRet{}

    putExtra := storage.PutExtra{}

    err := formUploader.Put(context.Background(), &ret, upToken, filename, localFile, size, &putExtra)

    if err != nil {
        return "", err
    }

    return ret.Key, nil
}

注意localFile io.Reader這個參數,調用upload方法需要傳一個byte。下面演示調用方法的代碼

func (u *UserController) UploadImage() {
    f, h, err := u.GetFile("image")

    if err != nil {
        u.Data["json"] = common.Response{
            Data:    [0]int{},
            Message: "上傳失敗",
            Code:    0,
        }

        u.ServeJSON()

        return
    }


    defer f.Close()

    file, _ := h.Open() // 這裏獲得的實際就是一個io,通過源碼看到這個open方法最終返回的是一個結構體,其內部包含了 io.Reader的接口
    
    // type File interface {
        // io.Reader
        // io.ReaderAt
        // io.Seeker
        // io.Closer
    // }


    unix := time.Now().Unix()

    timeByte := []byte(strconv.Itoa(int(unix)))

    filename := function.Md5(timeByte) // 這裏是計算了一個md5(time())的字符串作爲文件名

    if filename, err = qiniu.Upload(file, h.Size, filename); err != nil { // 通過h.size 即可獲得文件大小
        u.Data["json"] = common.Response{
            Data:    [0]int{},
            Message: "上傳失敗",
            Code:    0,
        }
    } else {
        u.Data["json"] = common.Response{
            Data: map[string]string{
                "filename": filename,
            },
            Message: "上傳成功",
            Code:    200,
        }
    }

    u.ServeJSON()
}

致謝

go 自身的特點不應是做web,web使用php,java就夠了。一般用go都是寫接口。所以上傳文件時不應先傳到本地再傳到七牛,我想很多初學者都在這裏被坑。特此寫一篇來解釋其使用方法。

希望本篇文章可以幫到你。謝謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章