如何使用dotnet核心控制器正确地从Azure存储中服务器文件?

问题描述

我在dotnet核心Web应用程序中有一个控制器,用于从Azure中的Azure存储帐户中获取资源,并将其提供给用户进行下载。用户无法直接访问Azure存储帐户,因此我的Web应用程序充当代理并在对文件进行服务之前对用户进行身份验证。

我的疑问是我的实现是否对大文件有效?我担心的是,DownloadToStreamAsync()实际上在提供服务之前会在Web应用程序的内存中获取整个文件

public async Task<IActionResult> Serve(string path)
{
    MemoryStream streamIn = null;
    CloudFile file = null;
    Stream fileStream = null;
    var filename = Path.GetFileName(path);

    // application-level permission checks checks
    
    // fetching file from Azure Storage
    try {
        var storageConnectionString = _azureOptions.AzureStorageAccountConnectionString;
        var storageAccount = CloudStorageAccount.Parse(storageConnectionString);
        var fileClient = storageAccount.CreateCloudFileClient();
        var share = fileClient.GetShareReference(_azureOptions.AzureStorageAccountContentShareName);
        var root = share.GetRootDirectoryReference();
        file = root.GetFileReference(path);
        if (!await file.ExistsAsync())
        {
            return NotFound();
        }
        streamIn = new MemoryStream();
        await file.DownloadToStreamAsync(streamIn);
        fileStream = await file.OpenReadAsync();
    } catch (StorageException e) {
        _logger.LogError($"Error while retrieving content resource: {path}",e);
        return NotFound();
    }  
    
    return File(fileStream,_getContentType(filename));
}

解决方法

您应该担心这个问题,因为您的代码会将整个Blob下载到内存中,然后再将其上传到客户端。这是非常低效的。

此外,您甚至没有在下载文件的地方使用MemoryStream。只需删除此代码:

streamIn = new MemoryStream();
await file.DownloadToStreamAsync(streamIn);

其余代码应将文件从Azure流传输并并行传输到客户端。