从文件复制到流的字节数为null

时间:2018-11-26 14:58:34

标签: c# amazon-s3 asp.net-core

我正在尝试将文件从Amazon s3复制到内存流,以便可以将其作为要下载的文件传递。

我正在从Amazon s3获取文件,但是当我尝试复制流时,我得到的是空值。

在复制之前,我已经检查了流是否已关闭,而没有。

var ms = new MemoryStream();
try
{
    GetObjectRequest getObjectRequest = new GetObjectRequest();
    getObjectRequest.BucketName = Bucketname;
    getObjectRequest.Key = Keyname;

    var getObjectResponse = client.GetObjectAsync(getObjectRequest);
    getObjectResponse.Wait();
    getObjectResponse.Result.ResponseStream.CopyToAsync(ms);
    var len = ms.Length;

    return File(ms.ToArray(), System.Net.Mime.MediaTypeNames.Application.Pdf, "filename");
}

var len = ms.Length; 

的值为18。

那么为什么没有内容被读取。 请指向正确的方向。

3 个答案:

答案 0 :(得分:4)

您的问题就在这里

getObjectResponse.Result.ResponseStream.CopyToAsync(ms);

谁在等待那个Task完成?没有人,所以您在操作过程中返回。

总体而言,代码应为:

try
{
    GetObjectRequest getObjectRequest = new GetObjectRequest();
    getObjectRequest.BucketName = Bucketname;
    getObjectRequest.Key = Keyname;

    var getObjectResponse = await client.GetObjectAsync(getObjectRequest);
    await getObjectResponse.ResponseStream.CopyToAsync(ms);
    var len = ms.Length;

    return File(ms.ToArray(), System.Net.Mime.MediaTypeNames.Application.Pdf, "filename");
}

请注意await用于异步操作的正确用法,尤其是在ASP.NET Core这样的Web框架中。

答案 1 :(得分:1)

await用于如下的GetObjectAsync方法,并将CopyToAsync用作@Camilo答案:

try
{
    GetObjectRequest getObjectRequest = new GetObjectRequest();
    getObjectRequest.BucketName = Bucketname;
    getObjectRequest.Key = Keyname;

    var getObjectResponse = await client.GetObjectAsync(getObjectRequest);
    getObjectResponse.Wait();
    await getObjectResponse.Result.ResponseStream.CopyToAsync(ms);
    var len = ms.Length; 
    return File(ms.ToArray(), System.Net.Mime.MediaTypeNames.Application.Pdf, "filename");
} 

或者您可以执行以下操作:

static async Task ReadStream()
{ 
    try
    {
        GetObjectRequest request = new GetObjectRequest
        {
            BucketName = bucketName,
            Key = keyName
        };
        using (GetObjectResponse response = await client.GetObjectAsync(getObjectRequest))
        using (Stream responseStream = response.ResponseStream)
        using (MemoryStream reader = new MemoryStream(responseStream))
        {
            //your codes
        }
    }
    catch (AmazonS3Exception e)
    {
        //Handle it
    }
    catch (Exception e)
    {
        //Handle it
    }
}

responseStream是您的流内容 消费就像:

ReadStream().Wait();

答案 2 :(得分:0)

您需要等待异步返回。如果您的方法未标记为异步并且不想将其标记为异步,则可以执行以下操作:

var ms = Task.Run<byte>(async () => await getObjectResponse.Result.ResponseStream.CopyToAsync(ms)).Result;

这将执行async方法并等待返回。您也无需将功能标记为异步。