dongtou5557 2018-01-12 07:44
浏览 155
已采纳

如何使用gin框架将文件上传到Amazon S3

I am trying to upload a file to Amazon S3 Using gin framework of Go. Since aws-sdc requires to read the file i need to open file using os.open('filename').But since i am getting the file from "formFile" I don't have the path of the file to open, so os.Open() is giving error

The system cannot find the file specified.

My approach is as follows

package controllers

import (
    "bytes"
    "log"
    "net/http"
    "os"

    "github.com/gin-gonic/gin"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/credentials"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

const (
    S3_REGION = "MY REGION"
    S3_BUCKET = "<MY BUCKET>"
)

func UploadDocument(c *gin.Context) {
    var Buf bytes.Buffer
    file, _ := c.FormFile("file")

    creds := credentials.NewSharedCredentials("", "default")

    s, err := session.NewSession(&aws.Config{
        Region:      aws.String(S3_REGION),
        Credentials: creds,
    })
    if err != nil {
        log.Fatal(err)
    }

    err = AddFilesToS3(s, file.fileName)
    if err != nil {
        log.Fatal(err)
    }
}

func AddFilesToS3(s *session.Session, fileDir string) error {
    file, err := os.Open(fileDir)
    if err != nil {
        return err
    }
    defer file.Close()

    fileInfo, _ := file.Stat()
    var size int64 = fileInfo.Size()
    buffer := make([]byte, size)
    file.Read(buffer)

    _, err = s3.New(s).PutObject(&s3.PutObjectInput{
        Bucket:               aws.String(S3_BUCKET),
        Key:                  aws.String("myfolder" + "/" + fileDir),
        ACL:                  aws.String("private"),
        Body:                 bytes.NewReader(buffer),
        ContentLength:        aws.Int64(size),
        ContentType:          aws.String(http.DetectContentType(buffer)),
        ContentDisposition:   aws.String("attachment"),
        ServerSideEncryption: aws.String("AES256"),
    })
    return err

}

I am sending my file through POSTMAN like this

enter image description here

what I need to pass to my 'AddFilesToS3' function, since I am sending just the file name, os.Open(fileDir) is failing to look to the actual path of the file. Where am I doing wrong or is there any better method available to do this?

  • 写回答

1条回答 默认 最新

  • duanjuan1103 2018-01-12 07:53
    关注

    You're not even reading the file from the form.

    You need to call FileHeader.Open. This returns a multipart.File which implements the standard io.Reader interface.

    You should change AddFilesToS3 to take a filename and io.Reader. This can then be called for files from gin as well as regular files.

      fileHeader, err := c.FormFile("file")
      // check err
      f, err := fileHeader.Open()
      // check err
      err = AddFilesToS3(s, fileHeader.fileName, f)
    

    And your AddFilesToS3 is now:

    func AddFilesToS3(s *session.Session, fileDir string, r io.Reader) error {
      // left as an exercise for the OP
    

    You may need to pass fileHeader.Size() as well.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 运筹学排序问题中的在线排序
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决
  • ¥30 求一段fortran代码用IVF编译运行的结果
  • ¥15 深度学习根据CNN网络模型,搭建BP模型并训练MNIST数据集
  • ¥15 lammps拉伸应力应变曲线分析
  • ¥15 C++ 头文件/宏冲突问题解决
  • ¥15 用comsol模拟大气湍流通过底部加热(温度不同)的腔体
  • ¥50 安卓adb backup备份子用户应用数据失败
  • ¥20 有人能用聚类分析帮我分析一下文本内容嘛
  • ¥15 请问Lammps做复合材料拉伸模拟,应力应变曲线问题