Asp.Net Core 2 + 谷歌云存储下载内存流

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

我正在开发 Asp.Net Core 2 Web Api,我必须创建一个端点来下载文件。该文件不是公开的,因此我无法使用谷歌存储对象的

MediaLink
属性。我正在使用他们的 C# 库

在这段代码中,您将看到下面的

_storageClient
是这样创建的:
_storageClient = StorageClient.Create(cred);
。客户端正在工作,只是显示它是哪个类。

[HttpGet("DownloadFile/{clientId}/{fileId}")]
public async Task<IActionResult> DownloadFile([FromRoute] long fileId, long clientId)
{
    // here there are a bunch of logic and permissions. Not relevant to the quest

    var stream = new MemoryStream();
    try
    {
        stream.Position = 0;
        var obj = _storageClient.GetObject("bucket name here", "file.png");
        _storageClient.DownloadObject(obj, stream);

        var response = File(stream, obj.ContentType, "file.png"); // FileStreamResult
        return response;
    }
    catch (Exception ex)
    {
        throw;
    }     
}

变量

obj
正常。所有属性均按预期填充。
stream
似乎已正确填充。它有长度和一切,但它返回给我一个 500 错误,我什至无法捕获。

我看不到我做错了什么,也许我是如何使用内存流的,但我什至无法捕获错误。

感谢您的帮助

c# google-cloud-storage memorystream
3个回答
4
投票

您正在倒带流,但在向其中写入任何内容之前 - 但之后您倒带它。我希望这会导致空响应而不是 500 错误,但我至少会将

stream.Position
调用移至下载后:

var obj = _storageClient.GetObject("bucket name here", "file.png");
_storageClient.DownloadObject(obj, stream);
stream.Position = 0;

请注意,在下载之前您不需要获取对象元数据。你可以只使用:

_storageClient.DownloadObject("bucket name here", "file.png", stream);
stream.Position = 0;

0
投票

解决方案可以如下所示。

[HttpGet("get-file")]
        public ActionResult GetFile()
        {
            var storageClient = ...;
            byte[] buffer;
            using (var memoryStream = new MemoryStream())
            {
                storageClient.DownloadObject("bucket name here"+"/my-file.jpg", memoryStream);
                buffer = memoryStream.ToArray();
            }

            return File(buffer, "image/jpeg", "my-file.jpg");
        }

0
投票

我有相同的代码按预期工作,当多个用户下载较大尺寸的文件时,它会引发内存异常。有什么更好的方法可以在不加载到系统内存的情况下处理下载。我使用 GCP 云进行 api 服务和 gcp 云存储

© www.soinside.com 2019 - 2024. All rights reserved.