1

如何从 s3 存储桶下载多个文件。我在 SO 上找不到更好的选择。这是我的单个文件下载代码。给定 URL 列表,我正在循环下载多个文件。

    public async Task Download(string url, Stream output)
    {
        var s3Uri = new AmazonS3Uri(url);
        GetObjectRequest getObjectRequest = new GetObjectRequest
        {
            BucketName = s3Uri.Bucket,
            Key = System.Net.WebUtility.UrlDecode(s3Uri.Key) 
        };

        using (var s3Client = new AmazonS3Client(s3Uri.Region))
        {
            // dispose the underline stream when writing to stream is done
            using (var getObjectResponse = await s3Client.GetObjectAsync(getObjectRequest).ConfigureAwait(false))
            {
                using (var responseStream = getObjectResponse.ResponseStream)
                {
                    await responseStream.CopyToAsync(output);
                }
            }
        }

        output.Seek(0L, SeekOrigin.Begin);
    }

下载给定 s3 url 的文件

var list = new List<Stream>();
foreach(var url in urls)
{
    var stream = new MemoryStream();
    await Download(url,ms);
    list.Add(stream);
}

有没有更好的选择从 S3 一次下载多个文件?

4

1 回答 1

1

我终于决定实现我自己的版本

public class StreamWrapper
{
    public string Url { get; set; }
    public Stream Content { get; set; }
    public string FileName { get; set; }
}


    public async Task Download(IList<StreamWrapper> inout, int maxConcurrentDownloads)
    {
        if (maxConcurrentDownloads <= 0)
        {
            maxConcurrentDownloads = 20;
        }

        if (!inout.HasAny())
            return;

        
            var tasks = new List<Task>();
            for (int i = 0; i < inout.Count; i++)
            {
                StreamWrapper wrapper = inout[i];
                AmazonS3Uri s3Uri = null;
                if (AmazonS3Uri.TryParseAmazonS3Uri(wrapper.Url, out s3Uri))
                {
                    tasks.Add(GetObject(s3Uri, wrapper.Content));
                }

                if (tasks.Count == maxConcurrentDownloads || i == inout.Count - 1)
                {
                    await Task.WhenAll(tasks);
                    tasks.Clear();
                }
            }                        
    }

    private async Task GetObject(AmazonS3Uri s3Uri, Stream output)
    {
        GetObjectRequest getObjectRequest = new GetObjectRequest
        {
            BucketName = s3Uri.Bucket,
            Key = System.Net.WebUtility.UrlDecode(s3Uri.Key)
        };

        using (var s3Client = new AmazonS3Client(s3Uri.Region))
        {
            // dispose the underline stream when writing to local file system is done
            using (var getObjectResponse = await s3Client.GetObjectAsync(getObjectRequest).ConfigureAwait(false))
            {
                using (var responseStream = getObjectResponse.ResponseStream)
                {
                    await responseStream.CopyToAsync(output);
                }
            }
        }

        output.Seek(0L, SeekOrigin.Begin);
    }
于 2020-11-13T20:37:25.183 回答