继快速入门之后,深入Gin的Web后端开发我们需要用到Gin的文件传输来获取用户上传的视频。
首先还是放上官方文档的地址: gin-gonic.com/zh-cn/
正文开始
这是官方的demo加上我提取文件后缀的操作(要尝试跑的小伙伴需要修改文件保存地址dst为你对应的地址)
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"log"
"net/http"
"path/filepath"
)
func main() {
router := gin.Default()
router.Static("static", "./src/ginLearn/fileTrans/static")
// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// 单文件
file, _ := c.FormFile("file")
suffix := filepath.Ext(file.Filename) //得到后缀
log.Println("filename= " + file.Filename + " size=" + file.Size + " suffix= " + suffix)
filename := "test" + suffix
dst := "./static/" + filename
// 上传文件至指定的完整文件路径
c.SaveUploadedFile(file, dst)
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
router.Run(":8080")
}
代码跑起来后,通过访问你电脑的IP地址:8080/upload就可以以POST的方式上传文件了。首先用gin创建了一个默认的路由router,之后使用router.MaxMultipartMemory设置了内存限制,就是 8*2^20 字节 也就是8MB了。
接下来就是通过gin.Context获取单个文件的对象,FormFile的定义如下:
func (c *Context) FormFile(name string) (*multipart.FileHeader, error)
返回值是一个FileHeader的结构体:
返回值是个结构体
type FileHeader struct {
Filename string
Header textproto.MIMEHeader
Size int64
// contains filtered or unexported fields
}
经常用到的就是存有文件名的字符串Filename和存有文件大小的Size,通过文件名我们可以拿到文件后缀,通过文件大小我们可以限制用户上传的文件大小。
这里我通过filepath包的Ext()函数获取上传文件的后缀名,再通过字符串拼接的方式修改文件名,生成文件保存地址。这里要注意的点就是地址拼接的时候前面的地址static一定得跟/,要不然你的文件名前面会多个static了,而且保存的位置也会前移。
拼接好文件保存地址后,我们可以使用SaveUploadedFile函数保存文件,函数定义如下:
func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error
第一个参数file传文件对象,dst为文件保存地址。
最后返回保存成功信息,文件上传流程至此结束。
测试
使用curl进行测试
curl -X POST http://localhost:8080/upload \
-F "file=@/Users/appleboy/test.zip" \
-H "Content-Type: multipart/form-data"
测试结果如图:
可以看到服务端返回上传成功信息,并且本地static目录下也能看见相应文件:
设置了路由的静态文件地址后,你也可以通过访问服务端的文件地址成功获取该文件:
router.Static("static", "存放静态文件的地址")
这里我将路由地址的static设置为访问地址,使用浏览器即可成功访问