使用 Go SDK v2 从 AWS S3 下载大文件

问题描述 投票:0回答:1

我需要实现一个从AWS S3下载大文件的功能。我尝试查看许多示例以及 AWS 文档并提出了这个解决方案:

    func (b *biz) S3DownloadFile(ctx context.Context, key string) ([]byte, error) {
    downloader := manager.NewDownloader(b.s3client, func(d *manager.Downloader) {
        d.PartSize = 5 * 1024 * 1024 // 5MB parts
    })
    buffer := manager.NewWriteAtBuffer([]byte{})
    _, err := downloader.Download(ctx, buffer, &s3.GetObjectInput{
        Bucket: &b.bucketName,
        Key:    &key,
    })
    if err != nil {
        log.Printf("Error downloading file: %v", err)
        return nil, err
    }
    return buffer.Bytes(), err
    }

然后在客户端,我只需获取此 API 并创建一个不可见的

a
标签,然后自动单击它即可下载文件。

问题

对于大文件,似乎这种方法将所有块下载到内存中,然后将整个 [] 字节切片发送到客户端。这使得客户不得不永远等待。

目标

我的目标是复制预签名 url 当前正在执行的操作,当单击预签名 url 时,文件将作为流下载到客户端,因此用户知道该文件正在下载。

我的发现

目前,我正在考虑2个解决方案:

  • 使用预先签名的 url -> 这可行,但我没有太多控件
  • 下载器已经使用 io.WriterAt 接口 -> 编写一个自定义编写器来处理此问题

除了我的解决方案之外,还有其他更好的方法来处理这个问题吗?谢谢

amazon-web-services go amazon-s3
1个回答
0
投票

我不知道你使用的是哪个模块,但是如果你使用aws sdk,你可以像这样得到

io.ReadCloser

我认为这将允许您以块的形式实现所需的操作,而无需一次将其全部移动到内存中。

import (
    "io"

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

var sess = session.Must(session.NewSession())

func NewS3Reader(bucket, key string) (io.ReadCloser, error) {
    objOut, err := s3.New(sess).GetObject(&s3.GetObjectInput{Bucket: &bucket, Key: &key})
    if err != nil {
        return nil, err
    }

    return objOut.Body, nil
}
© www.soinside.com 2019 - 2024. All rights reserved.