如何提升网站知名度,长沙商城网站建设,高质量网站外链建设大揭秘,国外购物网站推荐前些天发现了一个巨牛的人工智能学习网站#xff0c;通俗易懂#xff0c;风趣幽默#xff0c;忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie。 前言 在之前的文章中#xff0c;我们讲解了Gin框架的快速入门使用#xff0c;今天我们来聊聊如何使用… 前些天发现了一个巨牛的人工智能学习网站通俗易懂风趣幽默忍不住分享一下给大家。点击跳转到网站https://www.captainbed.cn/kitie。 前言 在之前的文章中我们讲解了Gin框架的快速入门使用今天我们来聊聊如何使用Gin实现文件上传。
Go标准库net/http对文件上传已经提供了非常完善的支持而Gin框架在其基础上进一步封装因此使用Gin开发文件上传功能时只需要简单几行代码便可以实现Gin框架支持单个文件与多个文件同时上传。
目录
编辑
前言
使用原生net/http库实现文件上传
使用Gin实现文件上传
单个文件上传
FormFile()获取文件
SaveUploadedFile()保存到本地
设置缓冲区大小
限制文件大小
限制文件类型
完整示例
测试文件上传
多个文件上传
MultipartForm()获取多个文件
测试文件上传
总结 使用原生net/http库实现文件上传
我们首先看看实现一个HTTP服务器提供文件上传功能的简单示例
package mainimport (ioio/ioutillognet/httpgithub.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.Filenameerr 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函数获取上传的文件对象以及文件的相关信息。然后通过headers.Header.Get函数获取上传文件的类型判断类型是否符合要求。接着使用ioutil.ReadAll函数读取文件的内容并将其存储在data变量中。然后通过headers.Filename获取上传文件的文件名并使用ioutil.WriteFile函数将文件内容写入到指定路径下的文件中。
使用Gin实现文件上传
单个文件上传
FormFile()获取文件
单文件上传使用gin.Context的FormFile()方法该方法的值为POST请求中文件上传字段的名称 engine : gin.Default()engine.POST(/upload, func(c *gin.Context) {file, err : c.FormFile(file)})engine.Run()
SaveUploadedFile()保存到本地
调用gin.Context的SaveUploadedFile()方法可以将文件保存到某个目录下 dst : ./uploads/ file.Filenamec.SaveUploadedFile(file,./uploadFile)设置缓冲区大小
Go默认文件上传缓冲区为32M当有大量文件上传时服务器内存的压力会很大因此可以通过MaxMultipartMemory属性来设置缓冲区大小 //8Mengine.MaxMultipartMemory 8 20限制文件大小
上传文件时不限制文件大小可以会导致服务存储空间暴涨因为有必须限制上传文件大小 fileMaxSize : 4 20 //4Mif 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个字节再调用http.DetectContentType()便可以获取文件的MIME值。
完整示例 package mainimport (fmtlognet/httpgithub.com/gin-gonic/gin)func main() {engine : gin.Default()//8Mengine.MaxMultipartMemory 8 20engine.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 //4Mif 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.Filenamec.SaveUploadedFile(file, dst)c.String(http.StatusOK, fmt.Sprintf(%s 上传成功!, file.Filename))})engine.Run()}测试文件上传
$ curl -F file./1.jpg -X POST http://localhost:8080/upload1.jpg 上传成功!
多个文件上传
MultipartForm()获取多个文件
如果要上传多个文件多次调用gin.Context的FormFile()方法也是可以的但更好的方式是使用gin.Context的MultipartForm()方法 package mainimport (fmtlognet/httpgithub.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对文件上传已经提供了非常完善的支持可以满足我们大部分需求Gin框架在其基础做了封装让我们使用起来更加方便迅速。
感谢阅读~