【问题标题】:How can I get the bytes of a GetObjectResponse from S3?如何从 S3 获取 GetObjectResponse 的字节?
【发布时间】:2016-03-12 16:48:47
【问题描述】:

我正在从 Amazon S3 检索文件。我想将文件转换为字节,以便我可以按如下方式下载它:

var download = new FileContentResult(bytes, "application/pdf");
download.FileDownloadName = filename;
return download;

我这里有文件:

var client = Amazon.AWSClientFactory.CreateAmazonS3Client(
        accessKey,
        secretKey,
        config
        );
GetObjectRequest request = new GetObjectRequest();
GetObjectResponse response = client.GetObject(request);          

我知道 response.WriteResponseStreamToFile() 但我想将文件下载到常规下载文件夹。如果我将 GetObjectResponse 转换为字节,我可以返回该文件。我该怎么做?

【问题讨论】:

    标签: c# amazon-web-services amazon-s3 download byte


    【解决方案1】:

    这是我为其他需要它的人找到的解决方案:

    GetObjectResponse response = client.GetObject(request);
    using (Stream responseStream = response.ResponseStream)
    {
        var bytes = ReadStream(responseStream);
        var download = new FileContentResult(bytes, "application/pdf");
        download.FileDownloadName = filename;
        return download;
    }
    

    public static byte[] ReadStream(Stream responseStream)
    {
        byte[] buffer = new byte[16 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = responseStream.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }
    

    【讨论】:

      【解决方案2】:

      只是另一种选择:

      Stream rs;    
      using (IAmazonS3 client = Amazon.AWSClientFactory.CreateAmazonS3Client())
      {
          GetObjectRequest getObjectRequest = new GetObjectRequest();
          getObjectRequest.BucketName = "mybucketname";
          getObjectRequest.Key = "mykey";
      
          using (var getObjectResponse = client.GetObject(getObjectRequest))
          {
                    getObjectResponse.ResponseStream.CopyTo(rs);
          }
      }    
      

      【讨论】:

      • 'ResponseStream.CopyTo' 比在其他答案中必须创建方法'ReadStream(Stream responseStream)' 更干净。您也可以使用“CopyToAsync”并使方法异步。
      【解决方案3】:

      我努力让 Alex 提供的更清洁的方法起作用(不确定我缺少什么),但我想不使用 Erica 提供的额外 ReadStream 方法(尽管它有效)......在这里这就是我最终要做的事情:

      var s3Client = new AmazonS3Client(AccessKeyId, SecretKey, Amazon.RegionEndpoint.USEast1);
          using (s3Client)
          {
              MemoryStream ms = new MemoryStream();
              GetObjectRequest getObjectRequest = new GetObjectRequest();
              getObjectRequest.BucketName = BucketName;
              getObjectRequest.Key = awsFileKey;
      
              using (var getObjectResponse = s3Client.GetObject(getObjectRequest))
              {
                  getObjectResponse.ResponseStream.CopyTo(ms);
              }
              var download = new FileContentResult(ms.ToArray(), "image/png"); //"application/pdf"
              download.FileDownloadName = ToFilePath;
              return download;
          }
      

      【讨论】:

        【解决方案4】:

        Stream 现在有异步方法。在 C# 8 中,您可以这样做:

        public async Task<byte[]> GetAttachmentAsync(string objectPointer)
        {
            var objReq = new GetObjectRequest
            {
                BucketName = "bucket-name",
                Key = objectPointer,    // the file name
            };
        
            using var objResp = await _s3Client.GetObjectAsync(objReq);
            using var ms = new MemoryStream();
            await objResp.ResponseStream.CopyToAsync(ms, _ct);  // _ct is a CancellationToken
            return ms.ToArray();
        }
        

        这不会在 IO 发生时阻塞任何线程。

        【讨论】:

        • 当我从同步方法调用它时,我对它的行为方式有点困惑。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 2014-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-04
        相关资源
        最近更新 更多