Gin框架完全使用指南 | Gin框架文件上传

公众号:程序员读书,欢迎关注

在之前的文章中,我们讲解了在Gin框架中获取参数的几种方式,这几种方式获取的都是字符串,除了字符串,我们也可以获取客户端上传的文件。

Gin框架支持单个文件与多个文件同时上传。

单个文件上传

单文件上传使用gin.ContextFormFile()方法,该方法的值为POST请求中文件上传字段的名称:

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

调用gin.ContextSaveUploadedFile()方法可以将文件保存到某个目录下:

css 复制代码
 dst := "./uploads/" + file.Filename
 c.SaveUploadedFile(file,"./uploadFile")

Go默认文件上传缓冲区为32M,当有大量文件上传时,服务器内存的压力会很大,因此可以通过MaxMultipartMemory属性来设置缓冲区大小:

ini 复制代码
 //8M
 engine.MaxMultipartMemory = 8 << 20

上传文件时,不限制文件大小可以会导致服务存储空间暴涨,因为有必须限制上传文件大小:

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

对文件类型,也可以进行限制:

go 复制代码
 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个字节,再调用http.DetectContentType()便可以获取文件的MIME值。

关于文件大小、类型等限制,下面是一个完整的示例:

go 复制代码
 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命令上传文件:

ruby 复制代码
 $ curl -F "file=@./1.jpg" -X POST "http://localhost:8080/upload"
 '1.jpg' 上传成功!

多个文件上传

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

go 复制代码
 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命令上传多个文件:

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

多文件上传有关于文件类型、大小限制等设置,都与单个文件上传类型一样,可以参与单文件上传的完整案例。

小结

Go标准库net/http对文件上传已经提供了非常完善的支持,而Gin框架在其基础上进一步封装,因此使用Gin开发文件上传功能时,只需要简单几行代码便可以实现。

相关推荐
Chan164 分钟前
【智能协同云图库】基于统一接口架构构建多维度分析功能、结合 ECharts 可视化与权限校验实现用户 / 管理员图库统计、通过 SQL 优化与流式处理提升数据
java·spring boot·后端·sql·spring·intellij-idea·echarts
库库林_沙琪马23 分钟前
REST接口幂等设计深度解析
spring boot·后端
IT_陈寒26 分钟前
Redis性能提升50%的7个关键优化策略,90%开发者都不知道第5点!
前端·人工智能·后端
智商偏低31 分钟前
ASP.NET Core 身份验证概述
后端·asp.net
冷冷的菜哥31 分钟前
ASP.NET Core使用MailKit发送邮件
后端·c#·asp.net·发送邮件·mailkit
canonical_entropy1 小时前
XDef:一种面向演化的元模型及其构造哲学
后端
小林coding1 小时前
再也不怕面试了!程序员 AI 面试练习神器终于上线了
前端·后端·面试
lypzcgf1 小时前
Coze源码分析-资源库-删除插件-后端源码-错误处理与总结
人工智能·后端·go·coze·coze源码分析·ai应用平台·agent平台
文心快码BaiduComate1 小时前
WAVE SUMMIT深度学习开发者大会2025举行 文心大模型X1.1发布
前端·后端·程序员
SamDeepThinking1 小时前
在Windows 11上配置Cursor IDE进行Java开发
后端·ai编程·cursor