Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between OpenReadAsync and DownloadFromStreamAsync functions of CloudBlockBlob

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.

like image 966
personofinterest713 Avatar asked Aug 10 '16 05:08

personofinterest713


3 Answers

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:  

Basic Concepts

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.  

Usage

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);
    }
}

Capturing Network requests via Fiddler

a) DownloadToStreamAsync

enter image description here enter image description here   b) OpenReadAsync

enter image description here enter image description here

  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.

like image 130
Jambor - MSFT Avatar answered Nov 20 '22 11:11

Jambor - MSFT


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);
like image 30
Eirik W Avatar answered Nov 20 '22 12:11

Eirik W


Answer from a member of Microsoft Azure (here):

The difference between DownloadStreamingAsync and OpenReadAsync 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.

like image 2
Cyber Progs Avatar answered Nov 20 '22 12:11

Cyber Progs