欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang使用Gin實現(xiàn)文件上傳的示例代碼

 更新時間:2024年02月03日 09:23:03   作者:鼠鼠我捏,要死了捏  
本文我們主要介紹了Golang如何使用Gin實現(xiàn)文件上傳,Go標準庫net/http對文件上傳已經(jīng)提供了非常完善的支持,而Gin框架在其基礎上進一步封裝,因此使用Gin開發(fā)文件上傳功能時,只需要簡單幾行代碼便可以實現(xiàn),需要的朋友可以參考下

前言

今天我們來聊聊如何使用Gin實現(xiàn)文件上傳。

Go標準庫net/http對文件上傳已經(jīng)提供了非常完善的支持,而Gin框架在其基礎上進一步封裝,因此使用Gin開發(fā)文件上傳功能時,只需要簡單幾行代碼便可以實現(xiàn),Gin框架支持單個文件與多個文件同時上傳。

使用原生net/http庫實現(xiàn)文件上傳

我們首先看看實現(xiàn)一個HTTP服務器,提供文件上傳功能的簡單示例

package main
 
import (
    "io"
    "io/ioutil"
    "log"
    "net/http"
 
    "github.com/julienschmidt/httprouter"
)
 
const (
    MAX_UPLOAD_SIZE = 1024 * 1024 * 20 //最大上傳大小,50MB
)
 
func main() {
    r := RegisterHandlers()
 
    http.ListenAndServe(":8080", r)  // 開啟一個http服務
}
 
// 定義路由
func RegisterHandlers() *httprouter.Router {
    router := httprouter.New()
 
    router.POST("/upload", uploadHandler)
 
    return router
}
// 文件上傳接口
func uploadHandler(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
    r.Body = http.MaxBytesReader(w, r.Body, MAX_UPLOAD_SIZE)
    if err := r.ParseMultipartForm(MAX_UPLOAD_SIZE); err != nil {
        log.Printf("File is too big")
        return
    }
    file, headers, err := r.FormFile("file")
    if err != nil {
        log.Printf("Error when try to get file: %v", err)
        return
    }
    //獲取上傳文件的類型
    if headers.Header.Get("Content-Type") != "image/png" {
        log.Printf("只允許上傳png圖片")
        return
    }
    data, err := ioutil.ReadAll(file)
    if err != nil {
        log.Printf("Read file error: %v", err)
        return
    }
    fn := headers.Filename
    err = ioutil.WriteFile("./video/"+fn, data, 0666)
    if err != nil {
        log.Printf("Write file error: %v", err)
        return
    }
    w.WriteHeader(http.StatusCreated)
    io.WriteString(w, "Uploaded successfully")
}

如上我們通過r.FormFile函數(shù)獲取上傳的文件對象,以及文件的相關信息。然后通過headers.Header.Get函數(shù)獲取上傳文件的類型,判斷類型是否符合要求。接著,使用ioutil.ReadAll函數(shù)讀取文件的內容,并將其存儲在data變量中。然后,通過headers.Filename獲取上傳文件的文件名,并使用ioutil.WriteFile函數(shù)將文件內容寫入到指定路徑下的文件中。

使用Gin實現(xiàn)文件上傳

單個文件上傳

FormFile()獲取文件

單文件上傳使用gin.ContextFormFile()方法,該方法的值為POST請求中文件上傳字段的名稱:

 engine := gin.Default()
 engine.POST("/upload", func(c *gin.Context) {
     file, err := c.FormFile("file")
 })
 engine.Run()

SaveUploadedFile()保存到本地 

調用gin.ContextSaveUploadedFile()方法可以將文件保存到某個目錄下:

 dst := "./uploads/" + file.Filename
 c.SaveUploadedFile(file,"./uploadFile")

設置緩沖區(qū)大小

Go默認文件上傳緩沖區(qū)為32M,當有大量文件上傳時,服務器內存的壓力會很大,因此可以通過MaxMultipartMemory屬性來設置緩沖區(qū)大?。?/p>

 //8M
 engine.MaxMultipartMemory = 8 << 20

限制文件大小

上傳文件時,不限制文件大小可以會導致服務存儲空間暴漲,因為有必須限制上傳文件大?。?/p>

 fileMaxSize := 4 << 20 //4M
 if int(file.Size) > fileMaxSize {
   c.String(http.StatusBadRequest, "文件不允許大小于4M")
   return
 }

限制文件類型

對文件類型,也可以進行限制:

 reader, err := file.Open()
 if err != nil {
   fmt.Println(err)
   return
 }
 b := make([]byte, 512)
 reader.Read(b)
 ?
 contentType := http.DetectContentType(b)
 if contentType != "image/jpeg" && contentType != "image/png" {
   c.String(http.StatusOK, "文件格式錯誤")
   return
 }

在上面的代碼中,我們讀取文件的前512個字節(jié),再調用http.DetectContentType()便可以獲取文件的MIME值。

完整示例

 package main
 ?
 import (
   "fmt"
   "log"
   "net/http"
 ?
   "github.com/gin-gonic/gin"
 )
 ?
 func main() {
   engine := gin.Default()
   //8M
   engine.MaxMultipartMemory = 8 << 20
   engine.POST("/upload", func(c *gin.Context) {
     file, err := c.FormFile("file")
     if err != nil {
       log.Println(err)
       c.String(http.StatusBadRequest, "文件上傳失敗")
       return
     }
     fileMaxSize := 4 << 20 //4M
     if int(file.Size) > fileMaxSize {
       c.String(http.StatusBadRequest, "文件不允許大小于32KB")
       return
     }
 ?
     reader, err := file.Open()
     if err != nil {
       fmt.Println(err)
       return
     }
     b := make([]byte, 512)
     reader.Read(b)
 ?
     contentType := http.DetectContentType(b)
     if contentType != "image/jpeg" && contentType != "image/png" {
       c.String(http.StatusOK, "文件格式錯誤")
       return
     }
 ?
     dst := "./uploads/" + file.Filename
     c.SaveUploadedFile(file, dst)
     c.String(http.StatusOK, fmt.Sprintf("'%s' 上傳成功!", file.Filename))
   })
   engine.Run()
 }
 ?

測試文件上傳

$ curl -F "file=@./1.jpg" -X POST "http://localhost:8080/upload"
 '1.jpg' 上傳成功!

多個文件上傳

MultipartForm()獲取多個文件

如果要上傳多個文件,多次調用gin.ContextFormFile()方法也是可以的,但更好的方式是使用gin.ContextMultipartForm()方法:

 package main
 ?
 import (
   "fmt"
   "log"
   "net/http"
 ?
   "github.com/gin-gonic/gin"
 )
 ?
 func main() {
   engine := gin.Default()
   engine.POST("/uploadMul", func(c *gin.Context) {
     form, err := c.MultipartForm()
     if err != nil {
       log.Println(err)
       c.String(http.StatusBadRequest, "文件上傳失敗")
       return
     }
     files := form.File["upload"]
     for _, file := range files {
       fmt.Println(file.Filename)
     }
     c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
   })
   engine.Run()
 }

測試文件上傳

運行程序后,使用curl命令上傳多個文件:

$ curl -F "upload=@./1.jpg" -F "upload=@./2.jpg" -X POST "http://localhost:8080/uploadMul
2 files uploaded

總結

Go標準庫net/http對文件上傳已經(jīng)提供了非常完善的支持,可以滿足我們大部分需求,Gin框架在其基礎做了封裝,讓我們使用起來更加方便迅速。

以上就是Golang使用Gin實現(xiàn)文件上傳的示例代碼的詳細內容,更多關于Golang Gin文件上傳的資料請關注腳本之家其它相關文章!

相關文章

最新評論