CloudBlockBlob.DownloadToStream与DownloadRangeToStream [英] CloudBlockBlob.DownloadToStream vs DownloadRangeToStream

查看:180
本文介绍了CloudBlockBlob.DownloadToStream与DownloadRangeToStream的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用ASP.NET Azure SDK从Blob存储下载图像.

Trying to use the ASP.NET azure SDK for downloading images from blob storage..

我在另一篇文章中读到,DownloadToStream确实将blob分解为较小的部分,并并行下载它们以提高性能.我相信这就是DownloadRangeToStream的目的.

I read in another post that DownloadToStream does break blobs up into smaller pieces and downloads them in parallel in order to increase performance. I believe this is what DownloadRangeToStream is for.

我无法找到任何文档或代码来确认有关DownloadToStream的声明,并且对此表示怀疑,因为它的运行时间与直接从Blob网址中下载的运行时间相同(每次下载.5-3s).这是我的两种下载方法的代码,它们具有相同的性能.

I have not been able to find any documentation or code confirming this statement about DownloadToStream, and am skeptical because it has the same runtime as just downloading straight from the blob url (.5-3s per download). Here is the code for both my download methods, giving about the same performance.

使用CloudBlockBlob.DownloadToStream:

private Bitmap DownloadFromBlob(String set) {

    CloudStorageAccount storageAccount = CloudStorageAccount.Parse( CloudConfigurationManager.GetSetting("StorageConnectionString"));

    CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

    CloudBlobContainer container = blobClient.GetContainerReference("templates");

    CloudBlockBlob blockBlob = container.GetBlockBlobReference(set + ".png");

    using (var memoryStream = new MemoryStream()) {
        blockBlob.DownloadToStream(memoryStream);

        return (memoryStream == null) ? null : (Bitmap)Image.FromStream(memoryStream);
    }
}

使用Image.FromStream:

private Bitmap DownloadImageFromUrl(string url) {
    try {
        using (WebClient client = new WebClient()) {
            byte[] data = client.DownloadData(url);
            using (MemoryStream mem = (data == null) ? null : new MemoryStream(data)) {
                return (data == null || mem == null) ? null : (Bitmap)Image.FromStream(mem);
            }
        }
    } catch (WebException e) {
        return null;
    }
}

我正在尝试增加.5-12 MB范围内图像的下载时间.我尝试为这些图像实现自己的DownloadRangeToStream方法,其代码如下.我需要这样做还是DownloadToStream已经为我做到了吗?此方法产生与上面的DownloadFromBlob方法相同的运行时..

I am trying to increase the download time of images that range from .5-12 MB. I tried to implement my own DownloadRangeToStream method for these images, the code for that is below. Do I need to do this or does DownloadToStream do it for me already? This method yields the same runtime as the DownloadFromBlob method above..

使用downloadRangeToStream:

private Image getImageFromStream(string set)
    {
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(
        CloudConfigurationManager.GetSetting("StorageConnectionString"));

        CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

        CloudBlobContainer container = blobClient.GetContainerReference("templates");

        CloudBlockBlob blockBlob = container.GetBlockBlobReference(set + ".png");

        using (MemoryStream ms = new MemoryStream())
        {

            ParallelDownloadBlob(ms, blockBlob);
            return (ms == null) ? null : Image.FromStream(ms);
        }
    }
private static void ParallelDownloadBlob(Stream outPutStream, CloudBlockBlob blob)
    {
        blob.FetchAttributes();
        int bufferLength = 1 * 1024 * 1024;//1 MB chunk
        long blobRemainingLength = blob.Properties.Length;
        Queue<KeyValuePair<long, long>> queues = new Queue<KeyValuePair<long, long>>();
        long offset = 0;
        while (blobRemainingLength > 0)
        {
            long chunkLength = (long)Math.Min(bufferLength, blobRemainingLength);
            queues.Enqueue(new KeyValuePair<long, long>(offset, chunkLength));
            offset += chunkLength;
            blobRemainingLength -= chunkLength;
        }
        Parallel.ForEach(queues,
            new ParallelOptions()
            {
        //Gets or sets the maximum number of concurrent tasks
        MaxDegreeOfParallelism = 10
            }, (queue) =>
            {
                using (var ms = new MemoryStream())
                {
                    blob.DownloadRangeToStream(ms, queue.Key, queue.Value);
                    lock (outPutStream)
                    {
                        outPutStream.Position = queue.Key;
                        var bytes = ms.ToArray();
                        outPutStream.Write(bytes, 0, bytes.Length);
                    }
                }
            });
    }

推荐答案

根据我的理解,CloudBlockBlob.DownloadToStreamImage.FromStream都只会发送下载流的请求,您可以利用

Per my understanding, both CloudBlockBlob.DownloadToStream and Image.FromStream would only send a request to download the stream, you could leverage Fiddler to capture the traffic as follows:

使用DownloadRangeToStream时,您可以将blob分成较小的部分,然后自己并行下载它们,以提高性能.这是我的代码段,您可以参考它.

When using DownloadRangeToStream, you could break your blob up into smaller pieces and download them in parallel by yourself in order to increase performance. Here is my code snippet, you could refer to it.

private static void ParallelDownloadBlob(Stream outPutStream, CloudBlockBlob blob)
{
    blob.FetchAttributes();
    int bufferLength = 1 * 1024 * 1024;//1 MB chunk
    long blobRemainingLength = blob.Properties.Length;
    Queue<KeyValuePair<long, long>> queues = new Queue<KeyValuePair<long, long>>();
    long offset = 0;
    while (blobRemainingLength > 0)
    {
        long chunkLength = (long)Math.Min(bufferLength, blobRemainingLength);
        queues.Enqueue(new KeyValuePair<long, long>(offset, chunkLength));
        offset += chunkLength;
        blobRemainingLength -= chunkLength;
    }
    Parallel.ForEach(queues,
        new ParallelOptions()
        {   
            //Gets or sets the maximum number of concurrent tasks
            MaxDegreeOfParallelism = 10
        }, (queue) =>
            {
                using (var ms = new MemoryStream())
                {
                    blob.DownloadRangeToStream(ms, queue.Key, queue.Value);
                    lock (outPutStream)
                    {
                        outPutStream.Position = queue.Key;
                        var bytes = ms.ToArray();
                        outPutStream.Write(bytes, 0, bytes.Length);
                    }
                }
            });
}

结果:

此外,还有一些关于并行上传/下载blob的博客,您可以参考它们(

Additionally, there are some blogs about upload/download blob in parallel, you could refer to them (blog1 and blog2).

这篇关于CloudBlockBlob.DownloadToStream与DownloadRangeToStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆