What is the difference between OpenReadAsync
and DownloadToStreamAsync
functions of CloudBlockBlob
in the Azure blob storage? Searched in google but could not find an answer.
Both OpenReadAsync and DownloadToStreamAsync could initiate an asynchronous operation for you to retrieve the blob stream. Based on my testing, you could have a better understanding of them by the following sections:
DownloadToStreamAsync:Initiates an asynchronous operation to download the contents of a blob to a stream.
OpenReadAsync:Initiates an asynchronous operation to download the contents of a blob to a stream.
a) DownloadToStreamAsync
Sample Code:
using (var fs = new FileStream(<yourLocalFilePath>, FileMode.Create))
{
await blob.DownloadToStreamAsync(fs);
}
b) OpenReadAsync
Sample Code:
//Set buffer for reading from a blob stream, the default value is 4MB.
blob.StreamMinimumReadSizeInBytes=10*1024*1024; //10MB
using (var blobStream = await blob.OpenReadAsync())
{
using (var fs = new FileStream(localFile, FileMode.Create))
{
await blobStream.CopyToAsync(fs);
}
}
a) DownloadToStreamAsync
b) OpenReadAsync
According to the above, DownloadToStreamAsync just sends one get request for retrieving blob stream, while OpenReadAsync sends more than one request to retrieving blob stream based on the “Blob.StreamMinimumReadSizeInBytes” you have set or by default value.
The difference between DownloadToStreamAsync
and OpenReadAsync
is that DownloadToStreamAsync
will download the contents of the blob to the stream before returning, but OpenReadAsync
will not trigger a download until the stream is consumed.
For example, if using this to return a file stream from an ASP.NET core service, you should use OpenReadAsync
and not DownloadToStreamAsync
:
Example with DownloadToStreamAsync
(not recommended in this case):
Stream target = new MemoryStream(); // Could be FileStream
await blob.DownloadToStreamAsync(target); // Returns when streaming (downloading) is finished. This requires the whole blob to be kept in memory before returning!
_logger.Log(LogLevel.Debug, $"DownloadToStreamAsync: Length: {target.Length} Position: {target.Position}"); // Output: DownloadToStreamAsync: Length: 517000 Position: 517000
target.Position = 0; // Rewind before returning Stream:
return File(target, contentType: blob.Properties.ContentType, fileDownloadName: blob.Name, lastModified: blob.Properties.LastModified, entityTag: null);
Example with OpenReadAsync
(recommended in this case):
// Do NOT put the stream in a using (or close it), as this will close the stream before ASP.NET finish consuming it.
Stream blobStream = await blob.OpenReadAsync(); // Returns when the stream has been opened
_logger.Log(LogLevel.Debug, $"OpenReadAsync: Length: {blobStream.Length} Position: {blobStream.Position}"); // Output: OpenReadAsync: Length: 517000 Position: 0
return File(blobStream, contentType: blob.Properties.ContentType, fileDownloadName: blob.Name, lastModified: blob.Properties.LastModified, entityTag: null);
Answer from a member of Microsoft Azure (here):
The difference between
DownloadStreamingAsync
andOpenReadAsync
is that the former gives you a network stream (wrapped with few layers but effectively think about it as network stream) which holds on to single connection, the later on the other hand fetches payload in chunks and buffers issuing multiple requests to fetch content. Picking one over the other one depends on the scenario, i.e. if the consuming code is fast and you have good broad network link to storage account then former might be better choice as you avoid multiple req-res exchanges but if the consumer is slow then later might be a good idea as it releases a connection back to the pool right after reading and buffering next chunk. We recommend to perf test your app with both to reveal which is best choice if it's not obvious.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With