Gin官方
官方给出了单文件与多文件的上传方式,也就是其实gin自己就实现了文件上传的功能,只不过看下来好像只能上传到本地,转发到别的服务器的话需要自己再加一些实现,并不是很难。
单文件
func main() {
router := gin.Default()
// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// 单文件
file, _ := c.FormFile("file")
log.Println(file.Filename)
dst := "./" + file.Filename
// 上传文件至指定的完整文件路径
c.SaveUploadedFile(file, dst)
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
})
router.Run(":8080")
}
多文件
查看详细示例代码.
func main() {
router := gin.Default()
// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
router.MaxMultipartMemory = 8 << 20 // 8 MiB
router.POST("/upload", func(c *gin.Context) {
// Multipart form
form, _ := c.MultipartForm()
files := form.File["upload[]"]
for _, file := range files {
log.Println(file.Filename)
// 上传文件至指定目录
c.SaveUploadedFile(file, dst)
}
c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
})
router.Run(":8080")
}
Gin的文件上传相关的其他特性
限制文件大小
Gin 除了提供上面的文件上传功能,还有提供限制文件上传大小的功能,这个在实际项目中会有较大的用途。
router := gin.Default()
router.MaxMultipartMemory = 8 << 20
使用 MaxMultipartMemory 来配置文件上传的大小限制,默认是32M。
文件下载服务
虽然 go 默认提供了文件服务,但是默认的文件服务会把整个文件夹下所有的文件都暴露,如果我们想做更多的控制就不太方便了,而 Gin 提供了文件下载的服务
func main() {
router := gin.Default()
router.GET("/local/file", func(c *gin.Context) {
c.File("local/file.go")
})
}
Gin
提供的文件服务,可以让我们非常方便的进行控制,甚至是动态文件,比默认的有更多的定制化玩法
大文件上传
这个是我从网上找'Gin 大文件传输'的时候,在一个论坛中找到的。网上大部分是前后端联调,协商一个分片,用来分片传输大数据,参考链接。然而论坛中说到:
其实完全不需要担心,net/http 在 readForm 的时候如果文件超过指定的最大内存占用,会自动写入临时文件,所以根本不会占用太多内存
https://github.com/golang/go/blob/master/src/mime/multipart/formdata.go#L91
我去查看了Gin读取文件相关的源码,发现底层确实就是调用readForm。也就是说完全不存在大文件撑爆内存的情况。
顺便去查看了一系列的Gin关于读取http.Request的实现的博客,对于Request的读取是这么说的:
我们可以知道该函数会将请求体中的数据解析为
multipart/form-data
,并且请求体中数据最大为maxMemory
个字节,还说文件部分存储于内存中,另外部分存储于磁盘中,不过这些都与我们的 URL 编码表单无关,唯一有关的,只是简单的一句,如果需要会调用ParseForm
。
也就是Gin原生读取方式就可以支持大文件传输,并且前端并不需要做分片,以form的方式提交即可
网上的选择
自定义分片上传
需要前后端协商一个分片,用来分片传输大数据。
具体的做法是前端将上传的文件进行分片,并给每个文件进行标号,之后分片发送Post。后端收到请求后进行校验与拼接。
书栈网的实现
观察书栈网的源码实现发现,他就是使用的Gin的原生FormFile读取,之后通过io.Copy保存。也就是Gin官方的做法。
总结
个人认为Gin已经把文件上传这部分做的很优秀了,如果没有更好的实现方式应该就会采用Gin原生文件上传方式。不过还是需要取舍存储在本地还是需要存储在云服务上。
标签:文件,分片,gin,router,Gin,上传 From: https://www.cnblogs.com/Vikyanite/p/17141666.html