美文网首页golangGolang语言社区Go
Go Gin 实现文件的上传下载流读取

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

作者: 五岁小孩 | 来源:发表于2020-08-06 10:13 被阅读0次

    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)
        c.Header("Content-Type", "application/octet-stream")
        c.Header("Content-Disposition", "attachment; filename="+fileName)
        c.Header("Content-Transfer-Encoding", "binary")
        c.Header("Cache-Control", "no-cache")
        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-Transfer-Encoding", "binary")
      
        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 实现文件的上传下载流读取

        本文链接:https://www.haomeiwen.com/subject/wxwhrktx.html