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")
}

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")
}
然后,直接在游览器访问,就能下载到了!!

但是呐:
有些响应,比如图片,浏览器就会显示这个图片,而不是下载,所以我们需要使浏览器唤起下载行为
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 入门案例(单文件)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 模块提供了生产级别的功能,比如健康检查,审计,指标收集,HTTP 跟踪等,帮助我们监控和管理Spring Boot 应用。 这个模块是一个采集应用内部信息暴露给外部的模块&…...
【MATLAB】安装Psychtoolbox
目录 一、下载Psychtoolbox工具包 1. 一个是这个ZTP文件 2. 分别下载 Subversion 1.7.x command-line client 和 gstreamer.freedesktop.org 二、解压工具包,保存至同一文件 三、安装到matlab 1. 安装psychtoolbox 2. 检查是否安装成功 一、下载Psychtoolbox…...
【Python机器学习】零基础掌握GradientBoostingClassifier集成学习
什么能有效地解决分类问题,特别是在数据复杂、特征多样的情况下? 面对这个问题,许多人可能会想到复杂的神经网络或深度学习方法。然而,有一种称为“梯度提升分类器”(Gradient Boosting Classifier)的算法,以其高准确度、灵活性和易用性赢得了大量用户的青睐。 假设在…...
RFNet模型数据集采集处理流程
文章目录 cityscapes数据集内容如何标注数据得到标签图片 cityscapes数据集内容 训练模型的时候下载了cityscapes里的disparity、gtFine和leftImg8bit。 共5000张图片。2975张训练,500张验证,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/ 你和你的朋友,两个人一起玩 Nim 游戏: 桌子上有一堆石头。 你们轮流进行自己的回合, 你作为先手 。 每一回合,轮到的人拿掉 1 - 3 块石头。 拿掉最后一块石头的人…...
如何在深度学习领域取得个人的成功
要在深度学习领域取得个人的成功,可以考虑以下建议: 学习深度学习的基础知识:首先,建立坚实的深度学习基础知识是非常重要的。你可以学习深度学习的基本概念、神经网络的原理、常用的深度学习框架(如TensorFlow、PyTor…...
数据结构【DS】B树
m阶B树的核心特性: Q:根节点的子树数范围是多少?关键字数的范围是多少? A:根节点的子树数∈[2, m],关键字数∈[1, m-1]。 Q:其他结点的子树数范围是多少?关键字数范围是多少? Q:对任…...
Chatgpt网页版根据关键词自动批量写原创文章软件【可多开自动登录切换gpt账号】
Chatgpt网页版根据关键词自动批量写原创文章软件介绍: 1、需要放入GPT账号和密码放入在账号库.txt里,可以放入多组账号密码,账号切换轮流使用。 2、可以自定义回答指令,也可多个回答指令随机切换。 3、可以给关键词加双标题&…...
研发效能认证学员作品:快速进行持续集成应用实践丨IDCF
作者:赖嘉明 研发效能(DevOps)工程师认证学员 随着数字化转型的推进及市场竞争的加剧,越来越多的企业也意识到持续集成的重要性。 而持续集成作为一种先进的软件开发实践和工具链,可以帮助企业实现自动化构建、集成和…...
中文编程开发语言工具系统化教程零基础入门篇和初级1专辑课程已经上线,可以进入轻松学编程
中文编程开发语言工具系统化教程零基础入门篇和初级1专辑课程已经上线,可以进入轻松学编程 学习编程捷径:(不论是正在学习编程的大学生,还是IT人士或者是编程爱好者,在学习编程的过程中用正确的学习方法 可以达到事半…...
2024年最新水果音乐制作软件FL Studio21需要多少钱呢?
水果,全称Fruity Loop Studio,简称FL Studio。是一款全能的音乐制作软件,经过二十多年的演化更迭,其各项功能非常的先进。其开创性的Pat\song模式,也为初学者的学习提供了便利。那么水果音乐制作软件FL Studio21需要多…...
当生成式AI遇到业务流程管理,大语言模型正在变革BPM
生成式AI对各领域有很大影响,一个方面在于它改变了很多固有业务的工作流。 工作流(Workflow)是业务流程的一种实现方式,一个业务流程往往包含多个工作流范式以及相关的数据、组织和系统。 因此,提及工作流必然离不开业…...
Kotlin数据流概览
文章目录 一 什么是数据流二 创建数据流三 修改数据流四 从数据流中进行收集五 数据流捕获异常六 在不同 CoroutineContext 中执行七 Jetpack 库中的数据流八 将基于回调的 API 转换为数据流 一 什么是数据流 数据流以协程为基础构建,可提供多个值。从概念上来讲&a…...
npm : 无法加载文件 C:\Program Files\nodejs\npm.ps1,因为在此系统上禁止运行脚本。
1、在vscode终端执行 get-ExecutionPolicy ,显示Restricted,说明状态是禁止的。 2、更改状态: set-ExecutionPolicy RemoteSigned 出现需要管理员权限提示,可选择执行 Set-ExecutionPolicy -Scope CurrentUser 出现的ExecutionPolicy参数后输…...
036-第三代软件开发-系统时间设置
第三代软件开发-系统时间设置 文章目录 第三代软件开发-系统时间设置项目介绍系统时间设置演示效果QML 实现小伙伴自创 TumblerQt 家 Tumbler C 端实现 总结一下 关键字: Qt、 Qml、 Time、 时间、 系统 项目介绍 欢迎来到我们的 QML & C 项目!…...
业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
站群服务器的应用场景都有哪些?
站群服务器主要是为了多个网站的托管和管理所设计的,可以通过集中管理和高效资源的分配,来支持多个独立的网站同时运行,让每一个网站都可以分配到独立的IP地址,避免出现IP关联的风险,用户还可以通过控制面板进行管理功…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
