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 .这是有用的,但消耗的内存与要存储的数据一样多.
您可以使用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我不知道的更好的解决方案,您必须自己进行测试。