Gin文件上传与下载处理

我在使用Gin框架处理文件上传和下载时遇到了一些问题:

  1. 如何正确地接收并保存客户端上传的文件?特别是大文件的分块上传该怎么实现?
  2. 下载文件时如何控制下载速度和并发量?需要设置哪些响应头才能确保文件正确下载?
  3. 文件上传后应该如何安全地存储和访问?如何防止恶意文件上传?
  4. 在处理多文件同时上传时,Gin的最佳实践是什么?有没有性能优化的建议?
  5. 如何实现断点续传功能?客户端和服务器端分别需要做哪些处理?

希望能得到具体的代码示例和实现思路,谢谢!

3 回复

使用Gin框架进行文件上传和下载非常方便。首先配置路由:

r.POST("/upload", uploadHandler)
r.GET("/download/:filename", downloadHandler)

上传文件的处理器实现如下:

func uploadHandler(c *gin.Context) {
    file, err := c.FormFile("file")
    if err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Upload failed"})
        return
    }
    dst := "./uploads/" + file.Filename
    c.SaveUploadedFile(file, dst)
    c.JSON(http.StatusOK, gin.H{"message": "File uploaded", "filename": file.Filename})
}

下载文件时,读取文件并返回给客户端:

func downloadHandler(c *gin.Context) {
    filename := c.Param("filename")
    filepath := "./uploads/" + filename
    file, err := os.Open(filepath)
    if err != nil {
        c.JSON(http.StatusNotFound, gin.H{"error": "File not found"})
        return
    }
    defer file.Close()

    fi, _ := file.Stat()
    c.Header("Content-Type", "application/octet-stream")
    c.Header("Content-Disposition", "attachment; filename="+filename)
    c.Header("Content-Length", fmt.Sprintf("%d", fi.Size()))
    c.File(filepath)
}

记得创建./uploads/目录来存放上传的文件,并确保有读写权限。


使用Gin框架处理文件上传和下载非常方便。对于上传:

func UploadFile(c *gin.Context) {
    file, err := c.FormFile("file") // 获取前端传来的文件
    if err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "上传失败"})
        return
    }
    dst := "./uploads/" + file.Filename // 指定保存路径
    c.SaveUploadedFile(file, dst)      // 保存文件
    c.JSON(http.StatusOK, gin.H{"message": "上传成功", "filename": file.Filename})
}

对于下载,可以这样实现:

func DownloadFile(c *gin.Context) {
    fileName := c.Param("name") // 获取请求中的文件名参数
    filePath := "./uploads/" + fileName
    file, err := os.Open(filePath)
    if err != nil {
        c.JSON(http.StatusNotFound, gin.H{"error": "文件不存在"})
        return
    }
    defer file.Close()

    c.Header("Content-Disposition", "attachment; filename="+fileName) // 强制下载
    c.Header("Content-Type", "application/octet-stream")
    fi, _ := file.Stat()
    c.Writer.Header().Set("Content-Length", strconv.FormatInt(fi.Size(), 10))

    io.Copy(c.Writer, file) // 将文件内容写入响应
}

记得创建./uploads/目录来存储文件,并确保有写入权限。同时在路由中添加对应的处理函数即可。

Gin 文件上传与下载处理

文件上传处理

package main

import (
	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	
	// 单个文件上传
	r.POST("/upload", func(c *gin.Context) {
		file, err := c.FormFile("file")
		if err != nil {
			c.String(400, "上传失败: %s", err.Error())
			return
		}
		
		// 保存文件到指定路径
		err = c.SaveUploadedFile(file, "./uploads/"+file.Filename)
		if err != nil {
			c.String(500, "保存文件失败: %s", err.Error())
			return
		}
		
		c.String(200, "文件 %s 上传成功", file.Filename)
	})
	
	// 多个文件上传
	r.POST("/multi-upload", func(c *gin.Context) {
		form, err := c.MultipartForm()
		if err != nil {
			c.String(400, "上传失败: %s", err.Error())
			return
		}
		
		files := form.File["files"]
		for _, file := range files {
			err := c.SaveUploadedFile(file, "./uploads/"+file.Filename)
			if err != nil {
				c.String(500, "保存文件 %s 失败: %s", file.Filename, err.Error())
				return
			}
		}
		
		c.String(200, "成功上传 %d 个文件", len(files))
	})
	
	r.Run(":8080")
}

文件下载处理

package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"path/filepath"
)

func main() {
	r := gin.Default()
	
	// 文件下载
	r.GET("/download", func(c *gin.Context) {
		filename := "example.txt"
		filePath := filepath.Join("./uploads", filename)
		
		// 检查文件是否存在
		if _, err := os.Stat(filePath); os.IsNotExist(err) {
			c.String(http.StatusNotFound, "文件不存在")
			return
		}
		
		// 设置响应头,告诉浏览器这是下载文件
		c.Header("Content-Description", "File Transfer")
		c.Header("Content-Transfer-Encoding", "binary")
		c.Header("Content-Disposition", "attachment; filename="+filename)
		c.Header("Content-Type", "application/octet-stream")
		
		// 发送文件
		c.File(filePath)
	})
	
	r.Run(":8080")
}

注意事项

  1. 上传文件大小限制:

    r.MaxMultipartMemory = 8 << 20  // 限制上传文件大小为8MB
    
  2. 建议对上传的文件进行安全验证,包括:

    • 文件类型检查
    • 文件大小限制
    • 文件名过滤
  3. 下载文件时建议验证用户权限,防止未授权访问

  4. 生产环境应考虑文件存储到云存储或专门的存储服务

回到顶部