问题描述
我在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流传输并并行传输到客户端。