Go的文件上传与下载(Gin)
1.安装Gin
1.1 步骤
-
首先,确保你已经安装了Go编程语言。你可以从官方网站(golang.org/dl/)上下载并安装适合你操作系统的Go软件包。
-
打开终端或命令提示符,并执行以下命令来确认Go是否正确安装:
go version -
确认Go成功安装后,接下来要安装Gin。在终端或命令提示符中执行以下命令:
go get -u github.com/gin-gonic/gin这个命令会自动从GitHub上下载Gin库,并将其安装在你的GOPATH目录中。
-
安装完成后,你可以在Go项目中导入Gin并开始使用。以下是一个简单的示例代码:
package main import ( "github.com/gin-gonic/gin" ) func main() { // 创建一个Gin实例 r := gin.Default() // 定义路由 r.GET("/", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "Hello, Gin!", }) }) // 运行服务器 r.Run() }
2.分层设计
2.1 规范
Gin是一个轻量级的Web框架,它没有固定的分层设置。但是,根据最佳实践,你可以根据应用的需求和规模自行设计分层结构。
- 路由层:负责定义路由和处理传入请求的处理程序。在这一层,你可以使用Gin的路由功能来定义URL路径和对应的处理函数。
- 处理层(处理器/服务层) :负责处理来自路由的请求,并将请求传递给适当的领域逻辑层。在这一层,你可以编写处理程序和服务,对请求进行验证、处理业务逻辑、操作数据库等。
- 领域逻辑层:处理业务逻辑的核心部分,独立于特定的框架。这一层包含了应用程序的核心业务规则和数据操作,与底层存储(如数据库)进行交互。
- 数据访问层:负责与数据存储(如数据库、缓存等)进行交互。这一层包含了对数据的持久化操作,如查询、写入和更新数据。
- 模型层:包含应用程序中使用的数据模型或结构。这一层定义了数据的结构和行为,以及与数据库交互时的ORM(对象关系映射)功能。
2.2 分层模块
- controller模块:处理匹配的路由并调用处理中间件完成业务
- main模块:完成服务的启动与配置
- service模块:放置业务处理的中间件
- uoload模块:动态生成文件存放地址,内含项目上传文件存放文件夹
3.实现服务
3.1 在upload中编写实现获取当前项目上传路径的文件
package upload
import (
"path/filepath"
"runtime"
)
func GetCurPath() (path string) {
//获取运行文件的路径
_, currentFilePath, _, _ := runtime.Caller(0)
//获取运行文件所在的包
projectPath := filepath.Dir(currentFilePath)
return projectPath
}
3.2 在service层编写文件上传下载的中间件
- 文件上传原理
1.单文件:从form-data表单中获取MultiPartFile,再从gin的上下文对象的FormFile中获取,用随机文件名进行存储(需要先获取项目文件存储路径)
2.多文件:先从gin的上下文对象中获取MultiPartForm文件列表,然后从列表中['字段名']获得上传的文件列表,然后依次进行单文件上传操作即可
- 单文件上传实现
package service
import (
"fileUploadAndDownload/upload"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"log"
"net/http"
"strings"
)
// 实现单文件上传的中间件
func SingleFileUploadMidWare(c *gin.Context) {
projectPath := upload.GetCurPath()
//直接从formfile中获得文件
file, _ := c.FormFile("file")
filename := file.Filename
extename := filename[strings.Index(filename, "."):]
uuid := uuid.New()
filename = uuid.String() + extename
log.Printf(filename)
//"E:/webServer/golang/file_test/upload"+"/images/"绝对路径测试
c.SaveUploadedFile(file, projectPath+"/images/"+filename)
log.Printf("/upload/images/" + filename)
c.JSON(http.StatusOK, gin.H{
"msg": "上传成功",
})
}
- 多文件上传实现
package service
import (
"fileUploadAndDownload/upload"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"log"
"net/http"
"strconv"
"strings"
)
// 实现单文件上传的中间件
func MultiFileUploadMidWare(c *gin.Context) {
projectPath := upload.GetCurPath()
//先获得包含所有文件的一个文件列表
form, _ := c.MultipartForm()
//从文件列表中获得所有键为files的文件
files := form.File["files"]
fileCount := len(files)
//遍历文件列表进行存储
for _, file := range files {
filename := file.Filename
extename := filename[strings.Index(filename, "."):]
uuid := uuid.New()
filename = uuid.String() + extename
log.Printf(filename)
//"E:/webServer/golang/file_test/upload"+"/images/"绝对路径测试
c.SaveUploadedFile(file, projectPath+"/images/"+filename)
log.Printf("/upload/images/" + filename)
}
c.JSON(http.StatusOK, gin.H{
"msg": "上传成功,共" + strconv.Itoa(fileCount) + "个文件",
})
}
- 文件下载原理
直接用gin的context对象File方法传入文件名即可将对应文件返回
- 实现
package service
import (
"fileUploadAndDownload/upload"
"github.com/gin-gonic/gin"
"log"
)
func FileDownloadMidware(fileName string, c *gin.Context) {
projectPath := upload.GetCurPath()
log.Println(projectPath + "/images/" + fileName)
c.File(projectPath + "/images/" + fileName)
}
3.3 在controller中编写控制器,调用中间件完成业务(较简单,不再多叙述)
- 单文件上传控制器
package controller
import (
"fileUploadAndDownload/service"
"github.com/gin-gonic/gin"
)
func SingleFileUpload(r *gin.Engine) {
//路由分组
apiRouter := r.Group("/singleFile")
{
apiRouter.POST("/upload", service.SingleFileUploadMidWare)
}
}
- 多文件上传控制器
package controller
import (
"fileUploadAndDownload/service"
"github.com/gin-gonic/gin"
)
func MultiFileUpload(r *gin.Engine) {
apiRouter := r.Group("/multiFile")
{
apiRouter.POST("/upload", service.MultiFileUploadMidWare)
}
}
- 文件下载控制器
package controller
import (
"fileUploadAndDownload/service"
"github.com/gin-gonic/gin"
"log"
)
func FileDownload(r *gin.Engine) {
apiRouter := r.Group("/download")
{
apiRouter.GET("/:fileName", func(c *gin.Context) {
fileName := c.Param("fileName")
log.Println(fileName)
service.FileDownloadMidware(fileName, c)
})
}
}
3.4 在mian包中配置服务
- 创建gin对象
r := gin.Default()
- 设置文件上传大小
r.MaxMultipartMemory = 10 << 20 //限制文件上传大小为10MB
- 配置文件上传下载的控制器
//为单文件和多文件上传配置处理
controller.SingleFileUpload(r)
controller.MultiFileUpload(r)
controller.FileDownload(r)
- 启动服务
const PORT = 3001
r.Run(":" + strconv.Itoa(PORT))