我将文件以blob的形式存储在Azure存储中,每个文件一个blob。文件大小最大可达~ 100 MB。
我正在实现一个API,它将这些文件作为ASP.NetCore3.1的IFormFile
接口的示例提供给使用者。
在API的服务器端实现中,我使用Azure的BlobClient.DownloadAsync()
方法下载文件。这将返回一个BlobDownloadInfo
示例,其中包含我需要的所有数据。具体来说,文件的内容通过BlobDownloadInfo.Value.Content
属性提供,该属性在运行时包含RetriableStreamImpl
的示例
我使用默认实现FileInfo
类从BlobDownaldInfo
Map到IFormFile
,如下所示:
BlobDownloadInfo response = await blobClient.DownloadAsync();
IFormFile file = new FormFile(
response.Value.Content,
0, // baseStreamOffset
response.Value.ContentLength,
"foo",
"bar.txt")
{
Headers = new HeaderDictionary(),
ContentType = response.Value.ContentType,
ContentDisposition = response.Value.Details.ContentDisposition
};
字符串
不幸的是,这段代码抛出了:
System.NotSupportedException : Specified method is not supported.
at Azure.Core.Pipeline.RetriableStream.RetriableStreamImpl.set_Position(Int64 value)
型
在我看来,好像FormFile
构造函数试图将流Position
设置为0,但该流是一个RetriableStreamImpl
,不允许设置其Position
属性。
我通过将RetriableStreamImpl
内容复制到MemoryStream
并将其传递到FormFile
构造函数来解决这个问题:
var memoryStream = new MemoryStream();
response.Value.Content.CopyTo(memoryStream);
型
这是一个很好的解决方案,我的问题是:这是一个很好的解决方案吗?现在是否有需要解决的性能问题?
2条答案
按热度按时间d7v8vwbk1#
将文件复制到内存流是个坏主意。它会减慢整个过程,如果同时发生许多下载,您将使系统内存过载。
相反,您应该尝试将流从blob存储“传递”到客户端。我们通常使用
FileStreamResult
和blob.OpenReadAsync
来实现这一点。blobClient.DownloadAsync
对我来说看起来很好,所以你可以尝试用FileStreamResult
替换IFile
。一些代码让你开始:
字符串
thtygnil2#
我在阅读blob存储并将流传递给其他方法时遇到了类似的问题,这对我很有效:
字符串
我返回了这个流,它是上面语句的输出。