本文学习视频https://www.bilibili.com/video/BV1GA411t7BR?spm_id_from=333.1007.top_right_bar_window_history.content.click
文件上传
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.POST("/testUpload", func(c *gin.Context) {
file, _ := c.FormFile("file")
c.JSON(200, gin.H{
"message": file,
})
})
r.Run(":8080")
}
对于文件的操作header里面的content-type一定要选multipart/form-data
然后body中设置如下,key的名字可以自定义,后面选择file,然后value可以选择select file
选择一个文件上传后返回如下
文件存到本地
用c.SaveUploadedFile
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.POST("/testUpload", func(c *gin.Context) {
file, _ := c.FormFile("file")
c.SaveUploadedFile(file, "./gin_"+file.Filename)
c.JSON(200, gin.H{
"message": file,
})
})
r.Run(":8081")
}
可以看下SaveUploaedFile的源码
func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error {
src, err := file.Open() //先把传过来的文件open,拿到文件的文件流
if err != nil {
return err
}
defer src.Close()
out, err := os.Create(dst) //在本地创建一个文件
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, src) //文件拷贝
return err
}
这里用上面的源码再试下一下
package main
import (
"github.com/gin-gonic/gin"
"io"
"os"
)
func main() {
r := gin.Default()
r.POST("/testUpload", func(c *gin.Context) {
file, _ := c.FormFile("file")
//c.SaveUploadedFile(file, "./gin_"+file.Filename)
in, _ := file.Open()
defer in.Close()
out, _ := os.Create("./gin-" + file.Filename)
defer out.Close()
io.Copy(out, in)
c.JSON(200, gin.H{
"message": file,
})
})
r.Run(":8081")
}
运行后post一个文件进去可以看到文件也是被存储到了本地。
文件操作的其他参数
比如在body中传一个type进去
代码中获取type参数并打印
package main
import (
"github.com/gin-gonic/gin"
"io"
"os"
)
func main() {
r := gin.Default()
r.POST("/testUpload", func(c *gin.Context) {
file, _ := c.FormFile("file")
//c.SaveUploadedFile(file, "./gin_"+file.Filename)
fileType := c.PostForm("type")
in, _ := file.Open()
defer in.Close()
out, _ := os.Create("./gin-" + file.Filename)
defer out.Close()
io.Copy(out, in)
c.JSON(200, gin.H{
"message": file,
"file_type": fileType,
})
})
r.Run(":8081")
}
前端返回结果如下
文件返回前端
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"io"
"os"
)
func main() {
r := gin.Default()
r.POST("/testUpload", func(c *gin.Context) {
file, _ := c.FormFile("file")
//c.SaveUploadedFile(file, "./gin_"+file.Filename)
in, _ := file.Open()
defer in.Close()
out, _ := os.Create("./" + file.Filename)
defer out.Close()
io.Copy(out, in)
c.Writer.Header().Add("Content-Disposition",
fmt.Sprintf("attachement; filename=%s",
file.Filename))
c.File("./" + file.Filename) //将文件传给前端
})
r.Run(":8081")
}
增加了c.Writer和c.File
可以看到上传的图片返回到了前端的body
多文件上传
package main
import (
"fmt"
"github.com/gin-gonic/gin"
"log"
)
func main() {
r := gin.Default()
r.POST("/testUpload", func(c *gin.Context) {
form, _ := c.MultipartForm()
file := form.File["file"]
fmt.Println(file)
for _, file := range file {
log.Println(file.Filename)
}
})
r.Run(":8081")
}
日志里显示如下
总结
- 读取文件
- c.FormFile(“前端放到file里面的name”)
- header里Content-Type选择multipart/form-data
- body里上传文件
- 本地写文件
- 原生:用file.Open(读上传文件), os.Create(创建新文件), io.Copy(拷贝)
- gin封装的SaveUploadedFile
- 给前端返回文件
- c.Writer.Header().Add(“Content-Disposition”,
fmt.Sprintf(“attachement; filename=%s”,
file.Filename))设置请求头 - c.File(“./” + file.Filename)
- c.Writer.Header().Add(“Content-Disposition”,