Go Gin实现文件上传下载的示例代码


Posted in Golang onApril 02, 2021

Go Gin 实现文件的上传下载流读取

文件上传

router

router.POST("/resources/common/upload", service.UploadResource)

service

type: POST

data:{
    “saveDir”:“保存的路径”,
    “fileName”:“文件名称不带后缀”
  }
// 上传文件
func UploadResource(c *gin.Context) {
 saveDirParam := c.PostForm("saveDir")  // 文件目录
 fileNameParam := c.PostForm("fileName") // 文件名称
 //目录
 var saveDir = ""
 //名称
 var saveName = ""
 //完整路径
 var savePath = ""
 //获取文件
 file, header, errFile := c.Request.FormFile("file")
 //处理获取文件错误
 if errFile != nil || common.IsEmpty(header.Filename) {
   c.JSON(http.StatusOK, gin.H{
     "success": false,
     "message": "请选择文件",
     "dir":   saveDir,
     "name":  saveName,
     "path":  savePath,
   })
   return
 }
 //目录请求参数为空
 if common.IsEmpty(saveDirParam) {
   c.JSON(http.StatusOK, gin.H{
     "success": false,
     "message": "请求参数错误!",
     "dir":   saveDir,
     "name":  saveName,
     "path":  savePath,
   })
   return
 }
 //如果上传的名称为空,则自动生成名称
 if common.IsEmpty(fileNameParam) {
   fileNameParam = GenerateResourceNo()
 }
 //获取上传文件的后缀(类型)
 uploadFileNameWithSuffix := path.Base(header.Filename)
 uploadFileType := path.Ext(uploadFileNameWithSuffix)
 //文件保存目录
 saveDir = "/attachment" + saveDirParam
 //保存的文件名称
 saveName = fileNameParam + uploadFileType
 savePath = saveDir + "/" + saveName
 //打开目录
 localFileInfo, fileStatErr := os.Stat(saveDir)
 //目录不存在
 if fileStatErr != nil || !localFileInfo.IsDir() {
   //创建目录
   errByMkdirAllDir := os.MkdirAll(saveDir, 0755)
   if errByMkdirAllDir != nil {
     logs.Error("%s mkdir error.....", saveDir, errByMkdirAllDir.Error())
     c.JSON(http.StatusOK, gin.H{
       "success": false,
       "dir":   saveDir,
       "name":  saveName,
       "path":  savePath,
       "message": "创建目录失败",
     })
     return
   }
 }
 ////上传文件前 先删除该资源之前上传过的资源文件
 ////(编辑-重新选择文件-需要先删除该资源之前上传过的资源文件)
  ////该代码执行的条件----上传的名称是唯一的,否则会出现误删
 ////获取文件的前缀
 //fileNameOnly := fileNameParam
 //deleteFileWithName(fileNameOnly, saveDir)
 //deleteFileWithName(fileNameOnly, model.WebConfig.ResourcePath+"/"+
 // model.WebConfig.WebConvertToPath)

 out, err := os.Create(savePath)
 if err != nil {
   logs.Error(err)
 }
 defer out.Close()
 _, err = io.Copy(out, file)
 if err != nil {
   c.JSON(http.StatusOK, gin.H{
     "success": false,
     "dir":   saveDir,
     "name":  saveName,
     "path":  savePath,
     "message": err.Error(),
   })
   return
 }

 //没有错误的情况下
 c.JSON(http.StatusOK, gin.H{
   "success": true,
   "dir":   saveDir,
   "name":  saveName,
   "path":  savePath,
   "message": "上传成功",
 })
 return
}

js提交例子:

注:需导入jquery.js 和 ajaxfileupload.js

//上传文件
    $.ajaxFileUpload(
      {
        url: '/resources/common/upload', //用于文件上传的服务器端请求地址
        secureuri: false, //是否需要安全协议,一般设置为false
        fileElementId: fileUploadDomId, //文件上传域的ID
        data: {
          "saveDir":fileSaveDir,
          "fileName":fileSaveName
        },
        dataType: 'json', //返回值类型 一般设置为json
        contentType:'application/json',//提交的数据类型
        async: false,
        success: function (data, status) //服务器成功响应处理函数
        {
          if (data.success){
            fileSaveName=fileSaveDir+"/"+data.name;
            console.log("上传成功,返回的文件的路径:",fileSaveName)
          }else{
            console.log("上传失败,返回的文件的路径:",fileSaveName)
            return
          }
        },
        error: function (data, status, e)//服务器响应失败处理函数
        {
          console.log("e==",e);
          return
        }
      }
    );

文件的下载

router

Type:‘GET'

普通链接格式非restful风格

参数url:下载的文件的路径

  • Jquery解码:decodeURIComponent(url);
  • Jquery编码:encodeURIComponent(url);

例:http://127.0.0.0.1:8080//pub/common/download?url=“/attachment/demo.docx”

router.GET("/pub/common/download", service.PubResFileStreamGetService)

service

//下载次数
func UserFileDownloadCommonService(c *gin.Context) {
  filePath := c.Query("url")
 //打开文件
 fileTmp, errByOpenFile := os.Open(filePath)
 defer fileTmp.Close()
  
  //获取文件的名称
  fileName:=path.Base(filePath)
 if common.IsEmpty(filePath) || common.IsEmpty(fileName) || errByOpenFile != nil {
    logs.Error("获取文件失败")
   c.Redirect(http.StatusFound, "/404")
   return
 } 
 c.Header("Content-Type", "application/octet-stream")
   //强制浏览器下载
 c.Header("Content-Disposition", "attachment; filename="+fileName)
 //浏览器下载或预览
 c.Header("Content-Disposition", "inline;filename="+fileName)
 c.Header("Content-Transfer-Encoding", "binary")
  c.Header("Cache-Control", "no-cache")

 c.File(filePath)
  return
}

文件流读取

router

Type:‘GET'

普通链接格式非restful风格

参数url:下载的文件的路径

  • Jquery解码:decodeURIComponent(url);
  • Jquery编码:encodeURIComponent(url);

例:http://127.0.0.0.1:8080//pub/common/file_stream?url=“/attachment/demo.docx”

router.GET("/pub/common/file_stream", service.PubResFileStreamGetService)

service

//map for Http Content-Type Http 文件类型对应的content-Type
var HttpContentType = map[string]string{
 ".avi": "video/avi",
 ".mp3": "  audio/mp3",
 ".mp4": "video/mp4",
 ".wmv": "  video/x-ms-wmv",
 ".asf": "video/x-ms-asf",
 ".rm":  "application/vnd.rn-realmedia",
 ".rmvb": "application/vnd.rn-realmedia-vbr",
 ".mov": "video/quicktime",
 ".m4v": "video/mp4",
 ".flv": "video/x-flv",
 ".jpg": "image/jpeg",
 ".png": "image/png",
}

//根据文件路径读取返回流文件 参数url
func PubResFileStreamGetService(c *gin.Context) {
filePath := c.Query("url")
//获取文件名称带后缀
fileNameWithSuffix := path.Base(filePath)
//获取文件的后缀
fileType := path.Ext(fileNameWithSuffix)
//获取文件类型对应的http ContentType 类型
fileContentType := HttpContentType[fileType]
if common.IsEmpty(fileContentType) {
 c.String(http.StatusNotFound, "file http contentType not found")
 return
}
c.Header("Content-Type", fileContentType)
c.File(filePath)
}

到此这篇关于Go Gin实现文件上传下载的示例代码的文章就介绍到这了,更多相关Go Gin 文件上传下载内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木! 

Golang 相关文章推荐
Go语言中break label与goto label的区别
Apr 28 Golang
彻底理解golang中什么是nil
Apr 29 Golang
golang 接口嵌套实现复用的操作
Apr 29 Golang
聊聊golang中多个defer的执行顺序
May 08 Golang
Go语言实现Snowflake雪花算法
Jun 08 Golang
如何解决goland,idea全局搜索快捷键失效问题
Apr 03 Golang
golang操作redis的客户端包有多个比如redigo、go-redis
Apr 14 Golang
golang定时器
Apr 14 Golang
Golang 实现 WebSockets 之创建 WebSockets
Apr 24 Golang
Golang实现可重入锁的示例代码
May 25 Golang
GoFrame基于性能测试得知grpool使用场景
Jun 21 Golang
Go各时间字符串使用解析
Apr 02 #Golang
一文读懂go中semaphore(信号量)源码
Apr 03 #Golang
go语言map与string的相互转换的实现
Apr 07 #Golang
Golang二维切片初始化的实现
Apr 08 #Golang
为什么不建议在go项目中使用init()
Apr 12 #Golang
Go语言操作数据库及其常规操作的示例代码
Apr 21 #Golang
golang判断key是否在map中的代码
Apr 24 #Golang
You might like
神族 Protoss 剧情介绍
2020/03/14 星际争霸
VML绘图板②脚本--VMLgraph.js、XMLtool.js
2006/10/09 PHP
php中的filesystem文件系统函数介绍及使用示例
2014/02/13 PHP
PHP解码unicode编码的中文字符代码分享
2014/08/13 PHP
使用Thinkphp框架开发移动端接口
2015/08/05 PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
2019/05/20 PHP
TP5框架安全机制实例分析
2020/04/05 PHP
PHP 实现base64编码文件上传出现问题详解
2020/09/01 PHP
jQuery EasyUI 开源插件套装 完全替代ExtJS
2010/03/24 Javascript
js监听滚动条滚动事件使得某个标签内容始终位于同一位置
2014/01/24 Javascript
js delete 用法(删除对象属性及变量)
2014/08/24 Javascript
js实现头像图片切割缩放及无刷新上传图片的方法
2015/07/17 Javascript
整理Javascript基础入门学习笔记
2015/11/29 Javascript
把json格式的字符串转换成javascript对象或数组的方法总结
2016/11/03 Javascript
浅析js的模块化编写 require.js
2016/12/07 Javascript
Vue.js中兄弟组件之间互相传值实例
2017/06/01 Javascript
jQuery、layer实现弹出层的打开、关闭功能
2017/06/28 jQuery
解决在vue+webpack开发中出现两个或多个菜单公用一个组件问题
2017/11/28 Javascript
swiper在vue项目中loop循环轮播失效的解决方法
2018/09/15 Javascript
Vue使用预渲染代替SSR的方法
2020/07/02 Javascript
如何实现echarts markline标签名显示自己想要的
2020/07/20 Javascript
vue3中轻松实现switch功能组件的全过程
2021/01/07 Vue.js
[03:51]吞吞映像 每周精彩击杀top10第二弹
2014/06/25 DOTA
Python语言描述连续子数组的最大和
2018/01/04 Python
Python实现京东秒杀功能代码
2019/05/16 Python
Python数据处理篇之Sympy系列(五)---解方程
2019/10/12 Python
新年福利来一波之Python轻松集齐五福(demo)
2020/01/20 Python
使用keras根据层名称来初始化网络
2020/05/21 Python
使用keras实现孪生网络中的权值共享教程
2020/06/11 Python
英国床和浴室商场:Bed & Bath Emporium
2018/05/20 全球购物
中国领先的汽车保养服务平台:途虎养车
2019/10/18 全球购物
LINUX下线程,GDI类的解释
2016/12/14 面试题
2014年党支部承诺书
2014/05/30 职场文书
2014年大堂经理工作总结
2014/11/21 职场文书
高中议论文(范文2篇)
2019/08/19 职场文书
Nginx已编译的nginx-添加新模块
2021/04/01 Servers