当前位置: 首页 > 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;…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

生成xcframework

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

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...