Golang使用Gin实现文件上传的示例代码

2024-03-01 0 535
目录
  • 前言
  • 使用原生net/http库实现文件上传
  • 使用Gin实现文件上传
    • 单个文件上传
      • FormFile()获取文件
      • SaveUploadedFile()保存到本地
      • 设置缓冲区大小
      • 限制文件大小
      • 限制文件类型
      • 完整示例
      • 测试文件上传
    • 多个文件上传
      • MultipartForm()获取多个文件
      • 测试文件上传
  • 总结

    前言

    今天我们来聊聊如何使用Gin实现文件上传。

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

    使用原生net/http库实现文件上传

    我们首先看看实现一个HTTP服务器,提供文件上传功能的简单示例

    package main

    import (
    \”io\”
    \”io/ioutil\”
    \”log\”
    \”net/http\”

    \”github.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.Filename
    err = 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.Filename
    c.SaveUploadedFile(file,\”./uploadFile\”)

    设置缓冲区大小

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

    //8M
    engine.MaxMultipartMemory = 8 << 20

    限制文件大小

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

    fileMaxSize := 4 << 20 //4M
    if 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 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 -F \”file=@./1.jpg\” -X POST \”http://localhost:8080/upload\”
    \’1.jpg\’ 上传成功!

    多个文件上传

    MultipartForm()获取多个文件

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

    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命令上传多个文件:

    $ curl -F \”upload=@./1.jpg\” -F \”upload=@./2.jpg\” -X POST \”http://localhost:8080/uploadMul
    2 files uploaded

    总结

    Go标准库net/http对文件上传已经提供了非常完善的支持,可以满足我们大部分需求,Gin框架在其基础做了封装,让我们使用起来更加方便迅速。

    以上就是Golang使用Gin实现文件上传的示例代码的详细内容,更多关于Golang Gin文件上传的资料请关注悠久资源网其它相关文章!

    您可能感兴趣的文章:

    • Golang使用Gin处理下载文件请求返回
    • Golang使用Gin框架实现HTTP上传文件过程介绍
    • golang gin框架实现大文件的流式上传功能
    • golang Gin上传文件返回前端及中间件实现示例
    • GolangGin框架实现文件下载功能的示例代码

    收藏 (0) 打赏

    感谢您的支持,我会继续努力的!

    打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
    点赞 (0)

    悠久资源 Golang Golang使用Gin实现文件上传的示例代码 https://www.u-9.cn/jiaoben/golang/179416.html

    常见问题

    相关文章

    发表评论
    暂无评论
    官方客服团队

    为您解决烦忧 - 24小时在线 专业服务