当前位置: 首页 > news >正文

Go学习第十六章——Gin文件上传与下载

Go web框架——Gin文件上传与下载

    • 1. 文件上传
      • 1.1 入门案例(单文件)
      • 1.2 服务端保存文件的几种方式
        • SaveUploadedFile
        • Create+Copy
      • 1.3 读取上传的文件
      • 1.4 多文件上传
    • 2. 文件下载
      • 2.1 快速入门
      • 2.2 前后端模式下的文件下载
      • 2.3 中文乱码问题

1. 文件上传

1.1 入门案例(单文件)

func main() {router := gin.Default()// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)// 单位是字节, << 是左移预算符号,等价于 8 * 2^20// gin对文件上传大小的默认值是32MB// 1. 设置路由器的最大内存限制为8MB,用于处理multipart表单数据中的文件上传。router.MaxMultipartMemory = 8 << 20 // 8 MiB// 2. 定义一个路由处理函数router.POST("/upload", func(c *gin.Context) {// 单文件// 3.通过c.FormFile函数获取HTTP请求上传的文件对象。//   其中参数"file"是上传表单中文件类型的name属性值。file, _ := c.FormFile("file")// 使用log包打印上传的文件名。log.Println(file.Filename)// 4. 指定上传文件的目标完整路径dst := "./" + file.Filename// 5. 使用c.SaveUploadedFile函数保存文件到指定路径下。c.SaveUploadedFile(file, dst)// 6. 使用c.String函数向客户端响应上传成功信息。c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))})router.Run(":8000")
}

image-20231028210743918

1.2 服务端保存文件的几种方式

SaveUploadedFile
func (c *Context) SaveUploadedFile(file *multipart.FileHeader, dst string) error

SaveUploadedFile函数用于将文件保存到指定的路径下。第一个参数是文件对象,第二个参数是保存文件的路径。

Create+Copy
func (c *Context) FormFile(name string) (*multipart.FileHeader, error)

FormFile函数用于获取上传的文件。它返回一个文件对象,其中包含了文件的元数据(名称、大小等)。我们可以使用这个文件对象去直接读取文件内容。

func main() {router := gin.Default()router.MaxMultipartMemory = 8 << 20 // 8 MiBrouter.POST("/upload", func(c *gin.Context) {file, _ := c.FormFile("file")log.Println(file.Filename)// 读取文件中的数据,返回文件对象fileRead, _ := file.Open()dst := "./" + file.Filename// 创建一个文件out, err := os.Create(dst)if err != nil {fmt.Println(err)}defer out.Close()// 拷贝文件对象到out中io.Copy(out, fileRead)c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))})router.Run(":8000")
}

一样是使用Apifox调用,没有什么毛病~

1.3 读取上传的文件

func (c *Context) FormFile(name string) (*multipart.FileHeader, error)

FormFile函数用于获取上传的文件。它返回一个文件对象,其中包含了文件的元数据(名称、大小等)。我们可以使用这个文件对象去直接读取文件内容。

func main() {router := gin.Default()router.MaxMultipartMemory = 8 << 20 // 8 MiBrouter.POST("/upload", func(c *gin.Context) {file, _ := c.FormFile("file")// 读取文件中的数据,返回文件对象fileRead, _ := file.Open()defer fileRead.Close()data, _ := io.ReadAll(fileRead)fmt.Println(string(data))c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))})router.Run(":8000")
}

在这里我们可以根据文件的内容来判断是否需要保存到服务器中。

1.4 多文件上传

func (c *Context) MultipartForm() (*multipart.Form, error)

MultipartForm函数用于获取上传的表单数据。它返回一个包含了文件对象的表单对象。

func main() {router := gin.Default()// 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)router.MaxMultipartMemory = 8 << 20 // 8 MiBrouter.POST("/upload", func(c *gin.Context) {// Multipart formform, _ := c.MultipartForm()files := form.File["upload[]"]  // 注意这里名字不要对不上了for _, file := range files {log.Println(file.Filename)// 上传文件至指定目录c.SaveUploadedFile(file, "./"+file.Filename)}c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))})router.Run(":8000")
}

2. 文件下载

2.1 快速入门

直接响应一个路径下的文件

func main() {router := gin.Default()router.GET("/download", func(c *gin.Context) {c.File("思考一个问题的四连问.txt")})router.Run(":8000")
}

然后,直接在游览器访问,就能下载到了!!

image-20231028212634272

但是呐:

有些响应,比如图片,浏览器就会显示这个图片,而不是下载,所以我们需要使浏览器唤起下载行为

c.Header("Content-Type", "application/octet-stream") // 表示是文件流,唤起浏览器下载,一般设置了这个,就要设置文件名
c.Header("Content-Disposition", "attachment; filename="+"牛逼.png") // 用来指定下载下来的文件名
c.Header("Content-Transfer-Encoding", "binary")   // 表示传输过程中的编码形式,乱码问题可能就是因为它
c.File("uploads/12.png")

完整代码:

func main() {router := gin.Default()router.GET("/download", func(c *gin.Context) {c.Header("Content-Type", "application/octet-stream")c.Header("Content-Disposition", "attachment; filename="+"牛逼.txt")c.File("思考一个问题的四连问.txt")})router.Run(":8000")
}

这样再使用游览器,就直接下载了!!

2.2 前后端模式下的文件下载

如果是前后端模式下,后端就只需要响应一个文件数据

文件名和其他信息就写在请求头中

c.Header("fileName", "xxx.png")
c.Header("msg", "文件下载成功")
c.File("uploads/12.png")

前端写法

async downloadFile(row) {this.$http({method: 'post',url: 'file/upload',data:postData,responseType: "blob"}).then(res => {const _res = res.datalet blob = new Blob([_res], {type: 'application/png'});let downloadElement = document.createElement("a");let href = window.URL.createObjectURL(blob); //创建下载的链接downloadElement.href = href;downloadElement.download = res.headers["fileName"]; //下载后文件名document.body.appendChild(downloadElement);downloadElement.click(); //点击下载document.body.removeChild(downloadElement); //下载完成移除元素window.URL.revokeObjectURL(href); //释放掉blob对象})}

2.3 中文乱码问题

前后端模式下的文件下载,进程会出现中文乱码问题,我们需要进行修改,并且指定一些格式

后端

func Download(c *gin.Context) {filename := url.QueryEscape("国家机密.txt")// 可唤起浏览器下载c.Header("Content-Disposition", "attachment; filename*=utf-8''"+filename) //c.Header("fileName", filename)c.File("uploads/国家机密.txt")
}

前端

async download() {let res = await axios.get("/download", {headers: {responseType: "blob"}})if (res.status === 200) {let binaryData = [];binaryData.push(res.data);let url = window.URL.createObjectURL(new Blob(binaryData)); //表示一个指定的file对象或Blob对象let a = document.createElement("a");document.body.appendChild(a);// 转码文件的标题let filename = decodeURI(res.headers.filename)// 调起文件下载a.href = url;a.download = filename; //命名下载名称a.click(); //点击触发下载window.URL.revokeObjectURL(url);}
}

这就是简单的文件上传和下载啦~~

相关文章:

Go学习第十六章——Gin文件上传与下载

Go web框架——Gin文件上传与下载 1. 文件上传1.1 入门案例&#xff08;单文件&#xff09;1.2 服务端保存文件的几种方式SaveUploadedFileCreateCopy 1.3 读取上传的文件1.4 多文件上传 2. 文件下载2.1 快速入门2.2 前后端模式下的文件下载2.3 中文乱码问题 1. 文件上传 1.1 …...

2.MySQL的调控按钮——启动选项和系统变量

2.MySQL的调控按钮——启动选项和系统变量 1.启动选项和配置文件1.1 在命令行上使用选项1.2 配置文件中使用选项1.2.1 配置文件路径1.2.2 配置文件的内容1.2.3 特定 MySQL 版本的专用选项组1.2.4 配置文件的优先级1.2.5 同一个配置文件中多个组的优先级1.2.6 defaults-file 的使…...

故障诊断模型 | Maltab实现CNN卷积神经网络故障诊断

文章目录 效果一览文章概述模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现CNN卷积神经网络故障诊断 模型描述 卷积神经网络(convolutional neural network)是具有局部连接、权重共享等特性的深层前馈神经网络,最早主要是用来处理图像信息。 相比于全…...

qt高精度定时器的使用停止线程应用

##线程停止 //线程停止应用 public: explicit WorkerThread(QObject *parent 0) :QThread(parent), m_bStopped(false){qDebug() << "Worker Thread : " << QThread::currentThreadId();}~WorkerThread(){stop();quit();wait();}void stop() {qDebug()…...

Spring Boot Actuator 介绍

Spring Boot Actuator是什么 Spring Boot Actuator 模块提供了生产级别的功能&#xff0c;比如健康检查&#xff0c;审计&#xff0c;指标收集&#xff0c;HTTP 跟踪等&#xff0c;帮助我们监控和管理Spring Boot 应用。 这个模块是一个采集应用内部信息暴露给外部的模块&…...

【MATLAB】安装Psychtoolbox

目录 一、下载Psychtoolbox工具包 1. 一个是这个ZTP文件 2. 分别下载 Subversion 1.7.x command-line client 和 gstreamer.freedesktop.org 二、解压工具包&#xff0c;保存至同一文件 三、安装到matlab 1. 安装psychtoolbox 2. 检查是否安装成功 一、下载Psychtoolbox…...

【Python机器学习】零基础掌握GradientBoostingClassifier集成学习

什么能有效地解决分类问题,特别是在数据复杂、特征多样的情况下? 面对这个问题,许多人可能会想到复杂的神经网络或深度学习方法。然而,有一种称为“梯度提升分类器”(Gradient Boosting Classifier)的算法,以其高准确度、灵活性和易用性赢得了大量用户的青睐。 假设在…...

RFNet模型数据集采集处理流程

文章目录 cityscapes数据集内容如何标注数据得到标签图片 cityscapes数据集内容 训练模型的时候下载了cityscapes里的disparity、gtFine和leftImg8bit。 共5000张图片。2975张训练&#xff0c;500张验证&#xff0c;1525test。每个目录下都有train、test和val的子目录,这些子…...

sql-50练习题6-10

sql练习题6-10题 前言数据库表结构介绍学生表课程表成绩表教师表 0-6 查询"李"姓老师的数量0-7 查询学过"李四"老师授课的同学的信息0-8 查询没学过"李四"老师授课的同学的信息0-9 查询学过编号为"01"并且也学过编号为"02"的…...

【刷题宝典NO.1】

Nim游戏 https://leetcode.cn/problems/nim-game/description/ 你和你的朋友&#xff0c;两个人一起玩 Nim 游戏&#xff1a; 桌子上有一堆石头。 你们轮流进行自己的回合&#xff0c; 你作为先手 。 每一回合&#xff0c;轮到的人拿掉 1 - 3 块石头。 拿掉最后一块石头的人…...

如何在深度学习领域取得个人的成功

要在深度学习领域取得个人的成功&#xff0c;可以考虑以下建议&#xff1a; 学习深度学习的基础知识&#xff1a;首先&#xff0c;建立坚实的深度学习基础知识是非常重要的。你可以学习深度学习的基本概念、神经网络的原理、常用的深度学习框架&#xff08;如TensorFlow、PyTor…...

数据结构【DS】B树

m阶B树的核心特性: Q&#xff1a;根节点的子树数范围是多少&#xff1f;关键字数的范围是多少&#xff1f; A&#xff1a;根节点的子树数∈[2, m],关键字数∈[1, m-1]。 Q&#xff1a;其他结点的子树数范围是多少&#xff1f;关键字数范围是多少&#xff1f; Q&#xff1a;对任…...

Chatgpt网页版根据关键词自动批量写原创文章软件【可多开自动登录切换gpt账号】

Chatgpt网页版根据关键词自动批量写原创文章软件介绍&#xff1a; 1、需要放入GPT账号和密码放入在账号库.txt里&#xff0c;可以放入多组账号密码&#xff0c;账号切换轮流使用。 2、可以自定义回答指令&#xff0c;也可多个回答指令随机切换。 3、可以给关键词加双标题&…...

研发效能认证学员作品:快速进行持续集成应用实践丨IDCF

作者&#xff1a;赖嘉明 研发效能&#xff08;DevOps&#xff09;工程师认证学员 随着数字化转型的推进及市场竞争的加剧&#xff0c;越来越多的企业也意识到持续集成的重要性。 而持续集成作为一种先进的软件开发实践和工具链&#xff0c;可以帮助企业实现自动化构建、集成和…...

中文编程开发语言工具系统化教程零基础入门篇和初级1专辑课程已经上线,可以进入轻松学编程

中文编程开发语言工具系统化教程零基础入门篇和初级1专辑课程已经上线&#xff0c;可以进入轻松学编程 学习编程捷径&#xff1a;&#xff08;不论是正在学习编程的大学生&#xff0c;还是IT人士或者是编程爱好者&#xff0c;在学习编程的过程中用正确的学习方法 可以达到事半…...

2024年最新水果音乐制作软件FL Studio21需要多少钱呢?

水果&#xff0c;全称Fruity Loop Studio&#xff0c;简称FL Studio。是一款全能的音乐制作软件&#xff0c;经过二十多年的演化更迭&#xff0c;其各项功能非常的先进。其开创性的Pat\song模式&#xff0c;也为初学者的学习提供了便利。那么水果音乐制作软件FL Studio21需要多…...

当生成式AI遇到业务流程管理,大语言模型正在变革BPM

生成式AI对各领域有很大影响&#xff0c;一个方面在于它改变了很多固有业务的工作流。 工作流&#xff08;Workflow&#xff09;是业务流程的一种实现方式&#xff0c;一个业务流程往往包含多个工作流范式以及相关的数据、组织和系统。 因此&#xff0c;提及工作流必然离不开业…...

Kotlin数据流概览

文章目录 一 什么是数据流二 创建数据流三 修改数据流四 从数据流中进行收集五 数据流捕获异常六 在不同 CoroutineContext 中执行七 Jetpack 库中的数据流八 将基于回调的 API 转换为数据流 一 什么是数据流 数据流以协程为基础构建&#xff0c;可提供多个值。从概念上来讲&a…...

npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。

1、在vscode终端执行 get-ExecutionPolicy &#xff0c;显示Restricted&#xff0c;说明状态是禁止的。 2、更改状态: set-ExecutionPolicy RemoteSigned 出现需要管理员权限提示&#xff0c;可选择执行 Set-ExecutionPolicy -Scope CurrentUser 出现的ExecutionPolicy参数后输…...

036-第三代软件开发-系统时间设置

第三代软件开发-系统时间设置 文章目录 第三代软件开发-系统时间设置项目介绍系统时间设置演示效果QML 实现小伙伴自创 TumblerQt 家 Tumbler C 端实现 总结一下 关键字&#xff1a; Qt、 Qml、 Time、 时间、 系统 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP&#xff0c;结果IP质量不佳&#xff0c;项目效率低下不说&#xff0c;还可能带来莫名的网络问题&#xff0c;是不是太闹心了&#xff1f;尤其是在面对海外专线IP时&#xff0c;到底怎么才能买到适合自己的呢&#xff1f;所以&#xff0c;挑IP绝对是个技…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...