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

yizhihongxing

下面我来详细讲解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框架实现文件下载功能的示例代码 - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • spring异步service中处理线程数限制详解

    Spring异步Service中处理线程数限制详解 异步Service基础知识 在Spring中,我们可以使用@Async注解来定义一个异步方法。这个方法会在调用时在单独的线程中执行,而不是在当前请求线程中执行。 以下是一个简单的示例,演示了如何使用@Async注解: @Service public class MyService { @Async publ…

    Java 2023年5月19日
    00
  • Java中json与javaBean几种互转的讲解

    下面是“Java中json与javaBean几种互转的讲解”的详细攻略。 一、什么是JSON JSON全称为JavaScript Object Notation,它是一种轻量级的数据交换格式,与XML格式相比,JSON格式更加简洁、易读、易写,可以在不同编程语言之间进行数据传输,并可以存储和描述各类结构化数据。 JSON格式由键值对组成,其中键是一个字符串,…

    Java 2023年5月26日
    00
  • 从原理聊JVM(二):从串行收集器到分区收集开创者G1

    作者:京东科技 康志兴 1 前言 随着Java的进化过程,涌现出各种不同的垃圾回收器,从串行执行到并行执行,从高吞吐到低延迟,终极目标就是让开发人员专注于程序的代码书写而无需关注内存管理。 JDK早期出现的垃圾回收器通常单独作用于不同分代,到后期出现的G1开始,才可以进行全区域收集。 关于垃圾回收器的基础知识请翻看前一篇:从原理聊JVM(一):染色标记和垃圾…

    Java 2023年4月24日
    00
  • Java SSM框架(Spring+SpringMVC+MyBatis)搭建过程

    下面是关于Java SSM框架(Spring+SpringMVC+MyBatis)搭建过程的完整攻略,包含两个示例说明。 Java SSM框架(Spring+SpringMVC+MyBatis)搭建过程 Java SSM框架是一种常用的Web应用程序开发框架,它由Spring、SpringMVC和MyBatis三个框架组成。在本文中,我们将介绍如何使用这三个…

    Java 2023年5月17日
    00
  • Java日常练习题,每天进步一点点(20)

    Java日常练习题,每天进步一点点(20)攻略 简介 这是一份Java日常练习题,每天练习一点点,逐步提高自己的编程能力。本文将对练习题进行一一讲解,帮助读者更好地理解题目并解决问题。 环境要求 Java编程环境(JDK) 编程工具 题目详解 1. 题目描述 编写程序,输入一个字符串,统计其中数字字符出现的次数。 示例1 请输入字符串:Hello123Wor…

    Java 2023年5月23日
    00
  • Java中数组在内存中存放原理的讲解

    下面是详细讲解“Java中数组在内存中存放原理的讲解”的完整攻略。 什么是数组 数组是一组同类型数据的集合,每个数据都可以通过一个索引来访问; 数组中同一类型的数据,所占用的内存大小相同; 数组存储在堆(heap)或栈(stack)中。 数组的内存分配 因为Java语言可以使用new运算符动态地创建数组,所以数组一般存储在堆(heap)中; 数组在内存中的存…

    Java 2023年5月26日
    00
  • 浅谈JavaScript中promise的使用

    首先需要了解promise是一种异步编程的解决方案,是一个对象,用来进行异步操作的状态管理和结果返回。 一、Promise的基本使用 1. Promise的三种状态 一个Promise对象有三种状态(state): pending(进行中) fulfilled(已成功) rejected(已失败) 2. Promise的基本结构 Promise对象的基本结构…

    Java 2023年5月23日
    00
  • java使用POI实现html和word相互转换

    针对“java使用POI实现html和word相互转换”的问题,我来详细讲解一下。 一、实现思路 POI 是 Apache 开源的用于操作 Microsoft Office 二进制文件格式的 Java API,它可以读取和写入 Excel、Word 和 PowerPoint 等文件。利用 POI,我们可以方便地将 word 和 html 相互转换。 具体实现…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部