下面我来详细讲解Golang Gin框架实现文件下载功能的完整攻略。
一、准备工作
在开始实现文件下载功能之前,我们需要先安装以下两个依赖:
- Gin框架:用于构建Web应用程序的Go语言框架。
- Gorm:用于在Go中操作关系型数据库的ORM库。
安装方法如下:
go get -u github.com/gin-gonic/gin
go get -u gorm.io/gorm
二、实现文件下载
1. 创建Gin路由
首先,我们需要创建一个Gin路由,用于响应文件下载的请求。
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/download", func(c *gin.Context) {
// TODO: 实现文件下载
})
r.Run(":8080")
}
2. 打开文件
接下来,我们需要打开要下载的文件。
func(c *gin.Context) {
filePath := c.Query("file_path")
file, err := os.Open(filePath)
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("Open file error: %s", err.Error()))
}
defer file.Close()
// TODO: 实现文件下载
}
c.Query("file_path")
用于获取请求参数中的文件路径。
3. 设置响应头
在打开文件后,我们需要设置响应头告诉浏览器要下载文件。
func(c *gin.Context) {
filePath := c.Query("file_path")
file, err := os.Open(filePath)
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("Open file error: %s", err.Error()))
}
defer file.Close()
// 设置响应头
c.Header("Content-Type", "application/octet-stream")
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(filePath)))
c.Header("Content-Transfer-Encoding", "binary")
c.Header("Cache-Control", "no-cache")
c.Header("Pragma", "no-cache")
// TODO: 实现文件下载
}
Content-Type
用于标识文件的MIME类型,Content-Disposition
用于告诉浏览器将文件作为附件下载,而非在浏览器中打开。filename
参数用于指定下载文件的名称。
4. 将文件写入响应
最后,我们需要将打开的文件写入到响应中返回给浏览器。
func(c *gin.Context) {
filePath := c.Query("file_path")
file, err := os.Open(filePath)
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("Open file error: %s", err.Error()))
}
defer file.Close()
// 设置响应头
c.Header("Content-Type", "application/octet-stream")
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(filePath)))
c.Header("Content-Transfer-Encoding", "binary")
c.Header("Cache-Control", "no-cache")
c.Header("Pragma", "no-cache")
// 将文件写入响应
_, err = io.Copy(c.Writer, file)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("Copy file error: %s", err.Error()))
}
}
io.Copy()
用于将打开的文件内容写入响应中。
三、示例说明
示例一
以下是一个完整的示例代码,它实现了从本地文件系统中下载文件的功能。
package main
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/download", func(c *gin.Context) {
filePath := c.Query("file_path")
file, err := os.Open(filePath)
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("Open file error: %s", err.Error()))
return
}
defer file.Close()
c.Header("Content-Type", "application/octet-stream")
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filepath.Base(filePath)))
c.Header("Content-Transfer-Encoding", "binary")
c.Header("Cache-Control", "no-cache")
c.Header("Pragma", "no-cache")
_, err = io.Copy(c.Writer, file)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("Copy file error: %s", err.Error()))
}
})
r.Run(":8080")
}
示例二
以下是一个示例代码,它演示了如何从数据库中获取文件内容并下载文件。
package main
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"github.com/gin-gonic/gin"
)
type File struct {
ID uint `gorm:"primaryKey"`
FileName string `gorm:"not null"`
FileSize int64 `gorm:"not null"`
Content []byte `gorm:"-"`
CreatedAt int64 `gorm:"autoCreateTime"`
UpdatedAt int64 `gorm:"autoUpdateTime"`
}
func main() {
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
if err != nil {
panic("Failed to connect database")
}
db.AutoMigrate(&File{})
r := gin.Default()
r.GET("/download", func(c *gin.Context) {
fileName := c.Query("file_name")
var file File
result := db.Where("file_name = ?", fileName).First(&file)
if result.Error != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("Get file error: %s", result.Error.Error()))
return
}
c.Header("Content-Type", "application/octet-stream")
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s", fileName))
c.Header("Content-Transfer-Encoding", "binary")
c.Header("Cache-Control", "no-cache")
c.Header("Pragma", "no-cache")
_, err = io.Copy(c.Writer, bytes.NewReader(file.Content))
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("Copy file error: %s", err.Error()))
}
})
r.Run(":8080")
}
这个示例中,我们定义了一个File
结构体来存储文件信息。在下载文件时,我们根据文件名从数据库中获取File
记录,然后将Content
字段中的文件内容写入响应中。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Golang Gin框架实现文件下载功能的示例代码 - Python技术站