The implementation methods for file upload and download in the Gin framework are as follows:
1. File upload
1.1 Single file upload
gofunc 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
gofunc 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
gofunc 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
gofunc 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
gofunc downloadFile(c *gin.Context) { filename := c.Param("filename") filepath := "./uploads/" + filename c.File(filepath) }
2.2 Download with custom filename
gofunc downloadFileWithCustomName(c *gin.Context) { filename := c.Param("filename") filepath := "./uploads/" + filename c.FileAttachment(filepath, "custom-name.pdf") }
2.3 Streaming download
gofunc 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
gofunc 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.