You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core FileStreamResult返回大Blob时偶现buffer空引用异常

解决ASP.NET Core返回大体积Azure Blob时FileStreamResult偶尔失败的问题

在Windows平台的.NET 6环境中,使用ASP.NET Core返回约1GB大小的Azure Blob时,FileStreamResult偶尔会执行失败。

相关代码示例

Azure.Storage.Blobs.BlobClient blob = container.GetBlobClient(fileName);
Stream stream = await blob.OpenReadAsync().ConfigureAwait(false);
return File(stream, MediaTypeNames.Application.Octet, fileName); 

捕获到的FileStreamResultExecutor内部错误日志

System.ArgumentNullException: 值不能为空。(参数 'buffer')
   在 System.Net.Http.HttpBaseStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   在 Azure.Core.Pipeline.ReadTimeoutStream.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   在 Azure.Core.Pipeline.RetriableStream.RetriableStreamImpl.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   在 Azure.Core.Pipeline.RetriableStream.RetriableStreamImpl.RetryAsync(Exception exception, Boolean async, CancellationToken cancellationToken)
   在 Azure.Core.Pipeline.RetriableStream.RetriableStreamImpl.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   在 Azure.Storage.LazyLoadingReadOnlyStream`1.DownloadInternal(Boolean async, CancellationToken cancellationToken)
   在 Azure.Storage.LazyLoadingReadOnlyStream`1.ReadInternal(Byte[] buffer, Int32 offset, Int32 count, Boolean async, CancellationToken cancellationToken)
   在 Azure.Storage.LazyLoadingReadOnlyStream`1.ReadAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
   在 Microsoft.AspNetCore.Http.StreamCopyOperationInternal.CopyToAsync(Stream source, Stream destination, Nullable`1 count, Int32 bufferSize, CancellationToken cancel)
   在 Microsoft.AspNetCore.Internal.FileResultHelper.WriteFileAsync(HttpContext context, Stream fileStream, RangeItemHeaderValue range, Int64 rangeLength)

可行解决方案

1. 禁用Blob流的延迟加载

OpenReadAsync默认返回的延迟加载流(LazyLoadingReadOnlyStream)在处理大文件时,可能因异步加载时序问题导致buffer为空。通过配置BlobOpenReadOptions禁用延迟加载并调整缓冲区大小:

var options = new BlobOpenReadOptions(false) // 关闭延迟加载
{
    BufferSize = 4 * 1024 * 1024, // 设置4MB缓冲区,适配大文件传输
    CancellationToken = HttpContext.RequestAborted
};
Stream stream = await blob.OpenReadAsync(options).ConfigureAwait(false);
return File(stream, MediaTypeNames.Application.Octet, fileName);

2. 传递请求取消令牌

确保Blob读取操作绑定请求的取消令牌,避免请求中断时流状态异常:

var cancellationToken = HttpContext.RequestAborted;
Stream stream = await blob.OpenReadAsync(new BlobOpenReadOptions(false) 
{ 
    CancellationToken = cancellationToken 
}).ConfigureAwait(false);
return File(stream, MediaTypeNames.Application.Octet, fileName);

3. 临时文件中转(适合超大文件)

将Blob下载到本地临时文件,再通过PhysicalFileResult返回,规避流操作的不稳定问题:

var tempFilePath = Path.GetTempFileName();
try
{
    await blob.DownloadToAsync(tempFilePath, HttpContext.RequestAborted).ConfigureAwait(false);
    return PhysicalFile(tempFilePath, MediaTypeNames.Application.Octet, fileName);
}
finally
{
    // 请求完成后异步清理临时文件
    _ = Task.Run(() => File.Delete(tempFilePath), HttpContext.RequestAborted);
}

内容的提问来源于stack exchange,提问作者Linas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 06:08:11