10-Gin 文件上传 --[Gin 框架入门精讲与实战案例]

使用 Gin 框架处理文件上传是一个常见的任务,Gin 提供了简单而直观的方法来处理文件上传。下面将介绍如何用 Gin 实现文件上传功能。

1. 安装 Gin

如果你还没有安装 Gin,可以通过 Go 的包管理工具 go get 来安装:

go get -u github.com/gin-gonic/gin

2. 创建一个简单的文件上传接口

首先,你需要创建一个新的 Go 文件(例如 main.go),并编写以下代码:

package mainimport ("fmt""net/http""os""github.com/gin-gonic/gin"
)func main() {r := gin.Default()// 设置静态文件目录,方便前端访问上传的文件r.Static("/uploads", "./uploads")// 设置模板文件r.LoadHTMLGlob("templates/*")// 渲染表单页面r.GET("/upload", func(c *gin.Context) {c.HTML(http.StatusOK, "upload.html", nil)})// 处理文件上传r.POST("/upload", func(c *gin.Context) {// 单个文件上传file, err := c.FormFile("file")if err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("get form file err: %s", err.Error()))return}// 获取上传文件的原始文件名filename := file.Filename// 指定文件保存路径destination := "./uploads/" + filename// 创建 uploads 目录(如果不存在)err = os.MkdirAll("./uploads", os.ModePerm)if err != nil {c.String(http.StatusInternalServerError, fmt.Sprintf("mkdir err: %s", err.Error()))return}// 保存上传的文件到指定位置if err := c.SaveUploadedFile(file, destination); err != nil {c.String(http.StatusInternalServerError, fmt.Sprintf("upload file err: %s", err.Error()))return}// 返回成功信息c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", filename))})// 启动服务器r.Run(":8080") // 默认在 :8080 端口监听
}

3. 创建上传表单页面

在templates目录下创建一个名为 upload.html 的文件,用于展示文件上传表单:

<!DOCTYPE html>
<html>
<head><title>Upload File</title>
</head>
<body><h1>Upload a File</h1><form action="/upload" method="post" enctype="multipart/form-data">Select file to upload:<input type="file" name="file" id="file"><input type="submit" value="Upload File" name="submit"></form>
</body>
</html>

4. 运行应用

确保你的工作目录中有上述两个文件后,你可以通过命令行运行你的 Go 应用:

go run main.go

然后,在浏览器中访问 http://localhost:8080/upload,你应该能看到一个文件上传表单。选择一个文件并提交表单,文件将会被上传到服务器端的 ./uploads/ 目录中。

在这里插入图片描述

这个例子展示了如何使用 Gin 框架接收单个文件上传。如果你需要处理多个文件上传,可以使用 c.Request.MultipartForm.File 来获取所有上传的文件,并对每个文件调用 SaveUploadedFile 方法。

请注意,实际应用中你可能还需要考虑安全性问题,比如验证文件类型、限制文件大小等。此外,为了提高性能和可靠性,建议配置合适的中间件来处理这些额外的需求。

多文件上传–不同名字的多个文件

为了处理多文件上传,特别是当这些文件使用不同的表单字段名时,你可以利用 Gin 框架的灵活性来接收和保存这些文件。下面是一个完整的示例,它展示了如何创建一个多文件上传接口,并且每个文件都有不同的名字。

1. 安装 Gin

确保你已经安装了 Gin:

go get -u github.com/gin-gonic/gin

2. 创建 Go 应用程序

创建一个新的 Go 文件(例如 main.go),并编写以下代码:

package mainimport ("fmt""github.com/gin-gonic/gin""net/http""os""path/filepath"
)func main() {r := gin.Default()// 设置静态文件目录,方便前端访问上传的文件r.Static("/uploads", "./uploads")// 设置模板文件r.LoadHTMLGlob("templates/*")// 渲染表单页面r.GET("/upload", func(c *gin.Context) {c.HTML(http.StatusOK, "upload.html", nil)})// 处理多文件上传r.POST("/upload", func(c *gin.Context) {// 创建 uploads 目录(如果不存在)err := os.MkdirAll("./uploads", os.ModePerm)if err != nil {c.String(http.StatusInternalServerError, fmt.Sprintf("mkdir err: %s", err.Error()))return}// 获取所有表单数据form, _ := c.MultipartForm()files := form.Filevar fileNames []stringfor field, fileList := range files {fmt.Printf("Field: %s\n", field)for _, file := range fileList {// 获取上传文件的原始文件名fileName := file.Filename// 指定文件保存路径destination := filepath.Join("./uploads", fileName)// 保存上传的文件到指定位置if err := c.SaveUploadedFile(file, destination); err != nil {c.String(http.StatusInternalServerError, fmt.Sprintf("upload file err: %s", err.Error()))return}fileNames = append(fileNames, fileName)}}// 返回成功信息c.JSON(http.StatusOK, gin.H{"message": "Files uploaded successfully!","files":   fileNames,})})// 启动服务器r.Run(":8080") // 默认在 :8080 端口监听
}

3. 创建上传表单页面

在同一目录下创建一个名为 upload.html 的文件,用于展示文件上传表单:

<!DOCTYPE html>
<html>
<head><title>Upload Multiple Files</title>
</head>
<body><h1>Upload Multiple Files with Different Names</h1><form action="/upload" method="post" enctype="multipart/form-data">Select image to upload:<input type="file" name="image" id="image"><br><br>Select document to upload:<input type="file" name="document" id="document"><br><br>Select archive to upload:<input type="file" name="archive" id="archive"><br><br><input type="submit" value="Upload Files" name="submit"></form>
</body>
</html>

在这个例子中,我们定义了三个不同名字的文件输入框:imagedocumentarchive。你可以根据需要添加更多不同名字的文件输入框。

4. 运行应用

确保你的工作目录中有上述两个文件后,你可以通过命令行运行你的 Go 应用:

go run main.go

然后,在浏览器中访问 http://localhost:8080/upload,你应该能看到一个包含多个文件选择框的表单。选择文件并提交表单后,文件将会被上传到服务器端的 ./uploads/ 目录中,每个文件都按照其对应的表单字段名称进行处理。

在这里插入图片描述

在这里插入图片描述

这个示例展示了如何处理具有不同表单字段名的多文件上传。实际应用中,你可能还需要实现额外的功能,如文件类型验证、大小限制等,以增强安全性和用户体验。

文件上传 按照日期存储

为了按照日期存储上传的文件,你可以基于当前日期创建一个目录结构,例如 uploads/yyyy/mm/dd。当文件被上传时,根据上传时间将它们保存到对应的日期目录中。下面是一个完整的 Gin 文件上传示例,它展示了如何实现这一点。

1. 安装 Gin

确保你已经安装了 Gin:

go get -u github.com/gin-gonic/gin

2. 创建 Go 应用程序

创建一个新的 Go 文件(例如 main.go),并编写以下代码:

package mainimport ("fmt""github.com/gin-gonic/gin""net/http""os""path/filepath""time"
)// 获取按日期组织的上传路径
func getUploadPath() string {t := time.Now()return filepath.Join("uploads", t.Format("2006/01/02"))
}func main() {r := gin.Default()// 设置静态文件目录,方便前端访问上传的文件r.Static("/uploads", "./uploads")// 设置模板文件r.LoadHTMLGlob("templates/*")// 渲染表单页面r.GET("/upload", func(c *gin.Context) {c.HTML(http.StatusOK, "upload.html", nil)})// 处理多文件上传r.POST("/upload", func(c *gin.Context) {// 获取所有表单数据form, err := c.MultipartForm()if err != nil {c.String(http.StatusBadRequest, fmt.Sprintf("get multipart form err: %s", err.Error()))return}files := form.Filevar fileNames []stringfor field, fileList := range files {fmt.Printf("Field: %s\n", field)for _, file := range fileList {// 根据当前日期获取上传路径uploadPath := getUploadPath()// 创建日期目录(如果不存在)err = os.MkdirAll(uploadPath, os.ModePerm)if err != nil {c.String(http.StatusInternalServerError, fmt.Sprintf("mkdir err: %s", err.Error()))return}// 获取上传文件的原始文件名fileName := file.Filename// 指定文件保存路径destination := filepath.Join(uploadPath, fileName)// 保存上传的文件到指定位置if err := c.SaveUploadedFile(file, destination); err != nil {c.String(http.StatusInternalServerError, fmt.Sprintf("upload file err: %s", err.Error()))return}fileNames = append(fileNames, fileName)}}// 返回成功信息c.JSON(http.StatusOK, gin.H{"message": "Files uploaded successfully!","files":   fileNames,})})// 启动服务器r.Run(":8080") // 默认在 :8080 端口监听
}

3. 创建上传表单页面

在同一目录下创建一个名为 upload.html 的文件,用于展示文件上传表单:

<!DOCTYPE html>
<html>
<head><title>Upload Multiple Files</title>
</head>
<body><h1>Upload Multiple Files with Different Names</h1><form action="/upload" method="post" enctype="multipart/form-data">Select image to upload:<input type="file" name="image" id="image"><br><br>Select document to upload:<input type="file" name="document" id="document"><br><br>Select archive to upload:<input type="file" name="archive" id="archive"><br><br><input type="submit" value="Upload Files" name="submit"></form>
</body>
</html>

在这个例子中,我们定义了一个 getUploadPath 函数来生成基于当前日期的上传路径,并使用这个路径来保存文件。每当有文件上传时,都会检查和创建相应的日期目录,以确保文件被正确地保存到对应日期的子目录中。

4. 运行应用

确保你的工作目录中有上述两个文件后,你可以通过命令行运行你的 Go 应用:

go run main.go

然后,在浏览器中访问 http://localhost:8080/upload,你应该能看到一个包含多个文件选择框的表单。选择文件并提交表单后,文件将会被上传到服务器端的 ./uploads/yyyy/mm/dd 目录中,每个文件都按照其上传的时间戳进行分类保存。

在这里插入图片描述

在这里插入图片描述

这种做法不仅有助于保持文件系统的整洁有序,还便于后续对文件进行管理和检索。如果你的应用需要处理大量的文件上传,这样的组织方式是非常有用的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/65838.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Promise实现原理解析,及实现方法。

Promise原理解析 Promise的介绍原理分析源码实现发布部分全部代码订阅部分基础代码简单发布订阅完整代码测试订阅能力链式调用的实现完整链式调用代码链式调用Promise完整功能代码 Promise的介绍 一&#xff0c;Promise的理解 在JavaScript中&#xff0c;Promise是一种用于处理…

http报头解析

http报文 http报文主要有两类是常见的&#xff0c;第一类是请求报文&#xff0c;第二类是响应报文&#xff0c;每个报头除了第一行&#xff0c;都是采用键值对进行传输数据&#xff0c;请求报文的第一行主要包括http方法&#xff08;GET&#xff0c;PUT&#xff0c; POST&#…

【日常开发】Git Stash使用技巧

文章目录 引言一、git stash 基础命令&#xff08;一&#xff09;存储当前工作区的修改&#xff08;二&#xff09;查看存储列表 二、查看存储的内容&#xff08;一&#xff09;查看特定存储的详细内容&#xff08;二&#xff09;查看特定存储修改的文件列表 三、恢复存储的修改…

微服务保护-sentinel

为什么要有微服务保护&#xff1f; 微服务保护是为了避免微服务雪崩而出现的&#xff0c;每个微服务能处理的请求是有限的&#xff0c;如果一个微服务出现问题导致一个请求进入微服务的时间太久&#xff0c;就会导致大量去请求停滞在微服务内部&#xff0c;这样就会过分占用系统…

【Redis】Redis 典型应用 - 缓存 (cache)

目录 1. 什么是缓存 2. 使用 Redis 作为缓存 3. 缓存的更新策略 3.1 定期生成 3.2 实时生成 4. 缓存的淘汰策略 5. 缓存预热, 缓存穿透, 缓存雪崩 和 缓存击穿 关于缓存预热 (Cache preheating) 关于缓存穿透 (Cache penetration) 关于缓存雪崩 (Cache avalanche) 关…

关于easy-es对时间范围查询遇到的小bug

前言&#xff1a;在使用easy-es之前作为一个小白的我只有es原生查询的基础&#xff0c;在自己通过查看官方文档自学easy-es遇到了一个挫折&#xff0c;其他的还好语法和MybatisPlus差不多&#xff0c;正以为我觉得很快就能入手&#xff0c;在对时间范围的判断就给我当头一棒&am…

从0到机器视觉工程师(一):机器视觉工业相机总结

目录 相机的作用 工业相机 工业相机的优点 工业相机的种类 工业相机知名品牌 光源与打光 打光方式 亮暗场照明 亮暗场照明的应用 亮暗场照明的区别 前向光漫射照明 背光照明 背光照明的原理 背光照明的应用 同轴光照明 同轴光照明的应用 总结 相机的作用 相机…

HTML——53. 创建表单

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>创建表单</title></head><body><!--form标签用于创建一个表单&#xff0c;会将里面的内容一起发送服务器&#xff0c;其结构类似于表格--><!--表…

逐行讲解大模型流式输出 streamer 源码

目录 简介TextStreamer 基础流式输出TextIterateStreamer 迭代器流式输出本地代码模型加载并前端展示streamlit 输出显示gradio 输出显示 vllm 部署模型并前端展示streamlit 输出显示gradio 输出显示 备注 简介 本文详细讲解了大模型流式输出的源码实现&#xff0c;包括TextSt…

java_使用阿里云oss服务存储图片

什么情况下可以使用阿里云oss服务存储图片&#xff1f; 对图片的访问速度有高要求时使用&#xff0c;方便用户快速的&#xff08;比如在网页页面中&#xff09;访问到图像 参考&#xff1a;41 尚上优选项目-平台管理端-商品信息管理模块-阿里云OSS介绍_哔哩哔哩_bilibili 1.…

第5章 共享内存范式:C语言层面

5.1OpenMP 5.1.1OpenMP的介绍 OpenMP三个原则 5.2OpenMP的使用 编译制导指令以#pragma omp 开始&#xff0c;后边跟具体的功能指令&#xff0c;格式如:#pragma omp 指令[子句[,子句].]。常用的功能指令如下: 5.2.1编译制导 5.2.2API和环境变量 具体案例-邻接矩阵 // 本代码…

web 开发全局覆盖文件上传身份验证漏洞利用

全局覆盖 首先认识全局变量和局部变量 再一个就是知道全局变量是全局使用的并且有个特点就是可以覆盖 这个就是全局变量我们输出一下发现 z居然等于函数内的计算值 把我们原来定义的全局变量 $z给覆盖了 看一下局部变量 这个时候 z就不会被覆盖 <?php $x1; $y2; …

No.2十六届蓝桥杯备战|练习题4道|数据类型|字符型|整型|浮点型|布尔型|signed|unsigned(C++)

B2002 Hello,World! - 洛谷 #include <iostream> using namespace std; int main() { cout << "Hello,World!" << endl; return 0; }打印飞机 #include <iostream> using namespace std;int main() {cout << " …

46. Three.js案例-创建颜色不断变化的立方体模型

46. Three.js案例-创建颜色不断变化的立方体模型 实现效果 知识点 Three.js基础组件 WebGLRenderer THREE.WebGLRenderer是Three.js提供的用于渲染场景的WebGL渲染器。它支持抗锯齿处理&#xff0c;可以设置渲染器的大小和背景颜色。 构造器 antialias: 是否开启抗锯齿&am…

5.系统学习-PyTorch与多层感知机

PyTorch与多层感知机 前言PyTroch 简介张量&#xff08;Tensor&#xff09;张量创建张量的类型数据类型和 dtype 对应表张量的维度变换&#xff1a;张量的常用操作矩阵或张量计算 Dataset and DataLoaderPyTorch下逻辑回归与反向传播数据表格 DNN&#xff08;全连结网络&#x…

WPF中的Microsoft XAML Behaviors包功能详解

什么是XAML Behaviors(行为) XAML Behaviors 提供了一种简单易用的方法&#xff0c;能以最少的代码为 Windows UWP/WPF 应用程序添加常用和可重复使用的交互性。 但是Microsoft XAML Behaviors包除了提供常用的XAML Behaviors之外&#xff0c;还提供了一些Trigger&#xff08…

Soildstate渗透测试

第一步&#xff1a;信息收集 Arp-scan -l 扫描本地存活ip&#xff0c;发现可疑ip 192.168.52.140 使用nmap -T4 -sV -sC -p- 192.168.52.140 对目标进行全端口扫描 同时使用dirb和dirsearch对目标网址进行目录爆破&#xff0c;这些网址都可以点进去看看进行一下信息收集看看是…

HTTP cookie与session

telnet命令 telnet 是一个网络协议&#xff0c;用于通过 TCP/IP 网络进行远程登录到服务器。它允许用户在本地计算机上通过网络连接到远程服务器&#xff0c;并在服务器上执行命令 telnet [主机名或IP地址] [端口号]//连接服务器 在 telnet 会话中&#xff0c;Ctrl] 会将你从…

【新年特辑】使用 React + TypeScript 开发新年祝福网页

&#x1f389; 新年将至&#xff0c;我决定开发一个独特的新年祝福网页&#xff0c;让每个人都能创建和分享自己的新年祝福。本文将详细介绍这个项目的开发过程&#xff0c;从技术选型到具体实现&#xff0c;希望能给大家一些启发。 一、项目概述 1.1 项目背景 在这个数字化的…

jmeter分布式启动

https://www.cnblogs.com/qtclm/p/11082081.html 1、代理机&#xff1a;输入“ipconfig”&#xff0c;找到IP地址&#xff0c;在Jmeter/bin/jmeter.properties设置remote host 启动jmeter server 1、控制机&#xff1a;输入“ipconfig”&#xff0c;找到IP地址&#xff0c;在J…