Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CloudBlob.DownloadToStream returns null

I'm trying to download a file from cloudBlob via stream. I refer to this article CloudBlob

Here is the code to download the blob

public Stream DownloadBlobAsStream(CloudStorageAccount account, string blobUri)
{
    Stream mem = new MemoryStream();
    CloudBlobClient blobclient = account.CreateCloudBlobClient();
    CloudBlockBlob blob = blobclient.GetBlockBlobReference(blobUri);

    if (blob != null)
        blob.DownloadToStream(mem);

    return mem;
}  

And the code to convert it into byte array

    public static byte[] ReadFully(Stream input)
    {
        byte[] buffer = new byte[16 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }  

But I always get null value. Below is the content of the streamed file.

enter image description here

What is wrong with this? Please help.

EDIT

Setting the Position to 0 inside ReadFully method is not allowed, so I put it inside DownloadBlobAsStream

This should work now:

public Stream DownloadBlobAsStream(CloudStorageAccount account, string blobUri)
{
    Stream mem = new MemoryStream();
    CloudBlobClient blobclient = account.CreateCloudBlobClient();
    CloudBlockBlob blob = blobclient.GetBlockBlobReference(blobUri);

    if (blob != null)
        blob.DownloadToStream(mem);
    mem.Position = 0;   
    return mem;
} 
like image 819
fiberOptics Avatar asked Jun 05 '12 05:06

fiberOptics


2 Answers

Your problem is that your input stream pointer is set to end of the steam (See the screen shot, Length and Position both shows same value) that's why when you read it you always get null. You would need to set to input stream pointer to 0 using Stream.Position = 0 as below:

public static byte[] ReadFully(Stream input)
{
    byte[] buffer = new byte[16 * 1024];

    input.Position = 0; // Add this line to set the input stream position to 0

    using (MemoryStream ms = new MemoryStream())
    {
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            ms.Write(buffer, 0, read);
        }
        return ms.ToArray();
    }
} 
like image 112
AvkashChauhan Avatar answered Nov 11 '22 00:11

AvkashChauhan


How about using the OpenRead() method on the CloudBlob object?

public static string ReadFully(string blobUri, string itemUri)
{
    // e.g. itemUri == "foo.txt"
    //   if there is a folder "bar" with foo.txt, provide instead: "bar/foo.txt"
    CloudBlobContainer cloudBlobContainer = new CloudBlobContainer(new Uri(blobUri));
    CloudBlob blobReference = cloudBlobContainer.GetBlobReference(itemUri);

    using (var stream = blobReference.OpenRead())
    {
        using (StreamReader reader = new StreamReader(stream))
        {
            return reader.ReadToEnd();
        }
    }
}
like image 10
devinbost Avatar answered Nov 11 '22 00:11

devinbost