简体   繁体   English

从 AWS S3 获取对象作为流

[英]Get object from AWS S3 as a stream

I am trying to to figure out whether it is possbile to return some sort of stream (possibly a memory stream?) of an object I get from my AWS S3 bucket.我试图弄清楚是否有可能返回我从 AWS S3 存储桶中获取的对象的某种流(可能是内存流?)。

The S3 bucket contains a lot of different type of images, documents etc. All those should be used on my website. S3 存储桶包含许多不同类型的图像、文档等。所有这些都应该在我的网站上使用。 However, I do not want to display the path to my AWS S3 bucket.但是,我不想显示我的 AWS S3 存储桶的路径。
That is why I am trying to create a stream and display the images and downloadable documents on the fly rather than with a full path.这就是为什么我试图创建一个流并动态显示图像和可下载文档而不是完整路径的原因。 Does this make sense?这有意义吗? :-) :-)

I am using the C#/.NET AWS SDK.我正在使用 C#/.NET AWS SDK。

Looking forward to hear about any ideas and directions pointed to!期待听到所指出的任何想法和方向!

public FileStream GetFile(string keyName)
{
    using (client = new AmazonS3Client(Amazon.RegionEndpoint.USEast2))
    {
        GetObjectRequest request = new GetObjectRequest
        {
            BucketName = bucketName,
            Key = keyName
        };

        using (GetObjectResponse response = client.GetObject(request))
        using (Stream responseStream = response.ResponseStream)
        using (StreamReader reader = new StreamReader(responseStream))
        {
            // The following outputs the content of my text file:
            Console.WriteLine(reader.ReadToEnd());
            // Do some magic to return content as a stream
        }
    }
}

In .NET 4, you can use Stream.CopyTo to copy the content of the ResponseStream (that is a Amazon.Runtime.Internal.Util.MD5Stream ) to a MemoryStream.在 .NET 4 中,您可以使用Stream.CopyTo将 ResponseStream(即Amazon.Runtime.Internal.Util.MD5Stream )的内容复制到 MemoryStream。

GetObjectResponse response = await client.GetObjectAsync(bucketName, keyName);
MemoryStream memoryStream = new MemoryStream();

using (Stream responseStream = response.ResponseStream)
{
    responseStream.CopyTo(memoryStream);
}

return memoryStream;

Where client.GetObjectAsync(bucketName, keyName) is an alternative to calling GetObject with the request you are creating.其中client.GetObjectAsync(bucketName, keyName)是使用您正在创建的请求调用GetObject的替代方法。

Even cheaper way is to use pre-signed URLs to objects in S3.更便宜的方法是使用 S3 中对象的预签名 URL。 That way you can return expiring URLs to your resources and do not need to do any stream copies.这样您就可以将过期的 URL 返回给您的资源,而无需进行任何流式复制。 Very low memory is required for that so you can use a very small and cheap VM.这需要非常低的内存,因此您可以使用非常小且便宜的 VM。

This approach would work for a few resources and only a few clients.这种方法适用于少数资源和少数客户。 With more requests you may hit AWS API limits.如果有更多请求,您可能会达到 AWS API 限制。

using (client = new AmazonS3Client(Amazon.RegionEndpoint.USEast2))
{
    var request = new GetPreSignedUrlRequest()
    {
        BucketName = bucketName,
        Key = keyName,
        Expires = DateTime.UtcNow.AddMinutes(10),
        Verb = HttpVerb.GET, 
        Protocol = Protocol.HTTPS
    };
    var url = client.GetPreSignedURL(request);
    // ... and return url from here. 
    // Url is valid only for 10 minutes
    // it can be used only to GET content over HTTPS
    // Any other operation like POST would fail.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM