blobclient.OpenRead
您可以使用以下代码返回包装的流,而不是从返回。我们的要求是从负载平衡的文件服务器启用并行和可恢复的 Azure blob 下载。代码中可能存在一些问题,请检查并根据需要修复它们。
在控制器中返回controller.File(stream, contentType, filename, true)
时,从最后一个参数开始,它会使用传入的 contentrangeheader 的值进行enableRangeProcessing=true
验证stream.CanSeek=true
和调用。stream.Seek
range.from
所以包装源return new SeekableBlobReadStream(blobclient)
并将其发送到控制器。
internal class SeekableBlobReadStream : Stream
{
private Stream stream;
private readonly BlobBaseClient client;
private readonly BlobProperties properties;
public SeekableBlobReadStream(BlobBaseClient client)
{
properties = client.GetProperties().Value;
this.client = client;
}
private void PrepareStream(long position = 0)
{
if (stream == null || position != 0)
{
if (stream != null)
stream.Dispose();
stream = client.OpenRead(new BlobOpenReadOptions(false) { Position = position });
}
}
public override bool CanRead => true;
public override bool CanSeek => true;
public override bool CanWrite => false;
public override long Length => properties.ContentLength;
public override long Position
{
get => (stream?.Position).GetValueOrDefault();
set => PrepareStream(value);
}
public override void Flush()
{
PrepareStream();
stream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
PrepareStream();
return stream.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Current:
offset = Position + offset;
break;
case SeekOrigin.End:
offset = Length - offset;
break;
}
PrepareStream(offset);
return stream.Position;
}
public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
}