amazon-web-services - Golang上传Http请求FormFile到Amazon S3

标签 amazon-web-services go amazon-s3

我正在创建一个微服务来处理一些上传到 Amazon S3 的附件,我想要实现的是接受一个文件,然后将它直接存储到我的 Amazon S3 存储桶,我当前的功能:

func upload_handler(w http.ResponseWriter, r *http.Request) {
  file, header, err := r.FormFile("attachment")

  if err != nil {
    fmt.Fprintln(w, err)
    return
  }

  defer file.Close()

  fileSize, err := file.Seek(0, 2) //2 = from end
    if err != nil {
         panic(err)
    }

    fmt.Println("File size : ", fileSize)

  bytes := make([]byte, fileSize)
  // read into buffer
  buffer := bufio.NewReader(file)
  _, err = buffer.Read(bytes)

  auth := aws.Auth{
        AccessKey: "XXXXXXXXXXX",
        SecretKey: "SECRET_KEY_HERE",
  }
  client := s3.New(auth, aws.EUWest)
  bucket := client.Bucket("attachments")

  err = bucket.Put(header.Filename, bytes, header.Header.Get("Content-Type"), s3.ACL("public-read"))

  if err != nil {
    fmt.Println(err)
    os.Exit(1)
  }
}

问题是存储在 S3 中的文件都已损坏,经过少量验证后似乎文件负载不是按字节读取的

如何将文件转换为字节并正确存储到S3?

最佳答案

使用ioutil.ReadAll:

bs, err := ioutil.ReadAll(file)
// ...
err = bucket.Put(
    header.Filename, 
    bs, 
    header.Header.Get("Content-Type"), 
    s3.ACL("public-read"),
)

Read 是一个具有微妙行为的低级函数:

Read reads data into p. It returns the number of bytes read into p. It calls Read at most once on the underlying Reader, hence n may be less than len(p). At EOF, the count will be zero and err will be io.EOF.

所以可能发生的事情是文件数据的某些子集连同一堆 0 被写入 S3。

ioutil.ReadAll 通过一遍又一遍地调用 Read 来填充动态扩展缓冲区,直到它到达文件末尾。 (所以也不需要 bufio.Reader)

此外,Put 函数在处理大文件时会有问题(使用 ReadAll 意味着整个文件必须适合内存),因此您可能需要使用 PutReader相反:

bucket.PutReader(
    header.Filename, 
    file, 
    fileSize, 
    header.Header.Get("Content-Type"), 
    s3.ACL("public-read"),
)

关于amazon-web-services - Golang上传Http请求FormFile到Amazon S3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32152005/

相关文章:

amazon-web-services - 如何使用 Terraform 加密 S3 存储桶

amazon-web-services - 如何将自定义域名的API网关迁移到另一个AWS账户?

go - C++ 中的 Const 引用和 Golang 中的等价物

go - 构建 Go 1.6 的问题

javascript - 使用 React Route 部署到 S3 后看到空白页面

actionscript-3 - 直接从 Flash 403 问题上传到 s3

amazon-web-services - 减少无服务器部署包的大小

java - AWS Java sdk如何将标签设置为卷

go - 如何使用带有用户 token E2E 的 CF 客户端

git - 如何在 AWS 上安装 Lambda 函数?