Golang Gin框架实现文件下载功能的示例代码

下面我来详细讲解Golang Gin框架实现文件下载功能的完整攻略。

下面我来详细讲解Golang Gin框架实现文件下载功能的完整攻略。

一、准备工作

在开始实现文件下载功能之前,我们需要先安装以下两个依赖:

  1. Gin框架:用于构建Web应用程序的Go语言框架。
  2. 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框架实现文件下载功能的示例代码

基础教程推荐