如何在S3中保存数据流?aws-sdk-go示例不起作用?

xxo*_*rde 6 amazon-s3 go aws-sdk-go

我试图将给定的数据流保存到S3兼容存储.在流结束之前,大小是未知的,并且可以在5MB到约500GB之间变化.

我尝试了不同的可能性,但没有找到比自己实现分片更好的解决方案.我最好的猜测是使用我的流填充一个固定大小的缓冲区并将其写入S3.有更好的解决方案吗?也许这种方式对我来说是透明的,而不是将整个流写入内存?

aws-sdk-go自述文件有一个示例程序,它从stdin获取数据并将其写入S3:https://github.com/aws/aws-sdk-go#using-the-go-sdk

当我尝试使用管道传输数据时,|我得到以下错误: failed to upload object, SerializationError: failed to compute request body size caused by: seek /dev/stdin: illegal seek 我做错了什么或示例不能正常工作?

我虽然尝试使用PutObject()client.PutObjectStreaming()进行 minio-go .这是有用的,但消耗的内存与要存储的数据一样多.

  1. 有更好的解决方案吗?
  2. 是否有一个小型示例程序可以将任意数据传输到S3?

mko*_*iva 6

您可以使用sdk的Uploader来处理大小未知的上传,但是您需要os.Stdin通过将其包装为来使“无法搜索” io.Reader。这是因为Uploader,虽然仅需要一个io.Reader作为输入主体,但在引擎盖下会进行检查以查看输入主体是否也是a Seeker,如果是,它会对其进行调用Seek。并且由于os.Stdin只是*os.File实现Seeker接口的,默认情况下,您会收到与相同的错误PutObjectWithContext

Uploader还允许你上传的数据块的大小,您可以配置,你还可以配置有多少块应同时上传的数据。

这是链接示例的修改版本,去除了可以保持不变的代码。

package main

import (
    // ...
    "io"
    "github.com/aws/aws-sdk-go/service/s3/s3manager"
)

type reader struct {
    r io.Reader
}

func (r *reader) Read(p []byte) (int, error) {
    return r.r.Read(p)
}

func main() {
    // ... parse flags

    sess := session.Must(session.NewSession())
    uploader := s3manager.NewUploader(sess, func(u *s3manager.Uploader) {
        u.PartSize = 20 << 20 // 20MB
        // ... more configuration
    })

    // ... context stuff

    _, err := uploader.UploadWithContext(ctx, &s3manager.UploadInput{
        Bucket: aws.String(bucket),
        Key:    aws.String(key),
        Body:   &reader{os.Stdin},
    })

    // ... handle error
}
Run Code Online (Sandbox Code Playgroud)

至于这是否是minio-go我不知道的更好的解决方案,您必须自己进行测试。