乐闻世界logo
搜索文章和话题

How to implement file upload and download in the Gin framework?

2月21日 15:16

The implementation methods for file upload and download in the Gin framework are as follows:

1. File upload

1.1 Single file upload

go
func uploadFile(c *gin.Context) { file, err := c.FormFile("file") if err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } // Save file dst := "./uploads/" + file.Filename if err := c.SaveUploadedFile(file, dst); err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } c.JSON(200, gin.H{ "message": "File uploaded successfully", "filename": file.Filename, "size": file.Size, }) }

1.2 Multiple file upload

go
func uploadMultipleFiles(c *gin.Context) { form, err := c.MultipartForm() if err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } files := form.File["files"] var uploadedFiles []string for _, file := range files { dst := "./uploads/" + file.Filename if err := c.SaveUploadedFile(file, dst); err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } uploadedFiles = append(uploadedFiles, file.Filename) } c.JSON(200, gin.H{ "message": "Files uploaded successfully", "files": uploadedFiles, }) }

1.3 File size limit

go
func uploadFileWithLimit(c *gin.Context) { // Limit file size to 10MB c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, 10<<20) file, err := c.FormFile("file") if err != nil { c.JSON(400, gin.H{"error": "File too large"}) return } // Handle file upload... }

1.4 File type validation

go
func uploadFileWithValidation(c *gin.Context) { file, err := c.FormFile("file") if err != nil { c.JSON(400, gin.H{"error": err.Error()}) return } // Validate file type allowedTypes := []string{"image/jpeg", "image/png", "image/gif"} fileHeader, err := file.Open() if err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } defer fileHeader.Close() buffer := make([]byte, 512) _, err = fileHeader.Read(buffer) if err != nil { c.JSON(500, gin.H{"error": err.Error()}) return } contentType := http.DetectContentType(buffer) isAllowed := false for _, allowedType := range allowedTypes { if contentType == allowedType { isAllowed = true break } } if !isAllowed { c.JSON(400, gin.H{"error": "Invalid file type"}) return } // Handle file upload... }

2. File download

2.1 Simple file download

go
func downloadFile(c *gin.Context) { filename := c.Param("filename") filepath := "./uploads/" + filename c.File(filepath) }

2.2 Download with custom filename

go
func downloadFileWithCustomName(c *gin.Context) { filename := c.Param("filename") filepath := "./uploads/" + filename c.FileAttachment(filepath, "custom-name.pdf") }

2.3 Streaming download

go
func downloadFileStream(c *gin.Context) { filename := c.Param("filename") filepath := "./uploads/" + filename file, err := os.Open(filepath) if err != nil { c.JSON(404, gin.H{"error": "File not found"}) return } defer file.Close() fileInfo, _ := file.Stat() c.Header("Content-Disposition", "attachment; filename="+filename) c.Header("Content-Type", "application/octet-stream") c.Header("Content-Length", strconv.FormatInt(fileInfo.Size(), 10)) http.ServeContent(c.Writer, c.Request, filename, fileInfo.ModTime(), file) }

2.4 Resumable download

go
func downloadFileWithResume(c *gin.Context) { filename := c.Param("filename") filepath := "./uploads/" + filename file, err := os.Open(filepath) if err != nil { c.JSON(404, gin.H{"error": "File not found"}) return } defer file.Close() fileInfo, _ := file.Stat() // Handle Range request rangeHeader := c.GetHeader("Range") if rangeHeader != "" { // Parse Range header ranges := strings.Split(rangeHeader, "=")[1] parts := strings.Split(ranges, "-") start, _ := strconv.ParseInt(parts[0], 10, 64) file.Seek(start, 0) remaining := fileInfo.Size() - start c.Header("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, fileInfo.Size()-1, fileInfo.Size())) c.Header("Content-Length", strconv.FormatInt(remaining, 10)) c.Header("Accept-Ranges", "bytes") c.Status(206) // Partial Content io.CopyN(c.Writer, file, remaining) return } c.Header("Accept-Ranges", "bytes") http.ServeContent(c.Writer, c.Request, filename, fileInfo.ModTime(), file) }

3. Best practices

3.1 File storage

  • Use dedicated storage services (such as OSS, S3)
  • Use UUID or timestamp for filenames to avoid conflicts
  • Store files in directories by date or user

3.2 Security considerations

  • Validate file type and size
  • Scan uploaded files (virus detection)
  • Limit access permissions to upload directories
  • Encrypt sensitive files

3.3 Performance optimization

  • Use streaming for large files
  • Implement resumable download
  • Use CDN to accelerate file downloads
  • Enable gzip compression

3.4 Error handling

  • Provide clear error messages
  • Log upload and download activities
  • Implement retry mechanism

Through the above methods, you can implement secure and efficient file upload and download functionality.

标签:Gin