使用WCF以块的形式下载Azure blob

时间:2012-02-05 13:10:09

标签: wcf download azure-storage-blobs

我被要求提供一个WCF服务,允许将blob(可能为1GB)作为偏移byte[]以块的形式下载,供Silverlight应用程序使用。本质上,操作将有一个参数用于偏移的字节数和要返回的最大字节数,我认为没有任何复杂。

我到目前为止的代码是:

[OperationContract]
public byte[] Download(String url, int blobOffset, int bufferSize)
{
    var blob = new CloudBlob(url);

    using(var blobStream = blob.OpenRead())
    {
        var buffer = new byte[bufferSize];
        blobStream.Seek(blobOffset, SeekOrigin.Begin);
        int numBytesRead = blobStream.Read(buffer, 0, bufferSize);

        if (numBytesRead != bufferSize)
        {
            var trimmedBuffer = new byte[numBytesRead];
            Array.Copy(buffer, trimmedBuffer, numBytesRead);
            return trimmedBuffer;
        }
        return buffer;
    }
}

我测试了这个(虽然文件相对较小,大于2MB)并且确实有效,但我的问题是:

  • 有人可以建议改进代码吗?
  • 根据要求,是否有更好的方法?

2 个答案:

答案 0 :(得分:2)

                    using (BlobStream blobStream = blob.OpenRead())
                    {
                        bool getSuccess = false;
                        int getTries = 0;
                        rawBytes = new byte[blobStream.Length];
                        blobStream.Seek(0, SeekOrigin.Begin);
                        int blockSize = 4194304; //Start at 4 mb per batch
                        int index = 0;
                        int documentSize = rawBytes.Length;
                        while (getTries <= 10 && !getSuccess)
                        {
                            try
                            {
                                int batchSize = blockSize;
                                while (index < documentSize)
                                {
                                    if ((index + batchSize) > documentSize)
                                        batchSize = documentSize - index;
                                    blobStream.Read(rawBytes, index, batchSize);
                                    index += batchSize;
                                }
                                getSuccess = true;
                            }
                            catch (Exception e)
                            {
                                if (getTries > 9)
                                    throw e;
                                else
                                    blockSize = blockSize / 2; // Reduce by half for each attempt
                            }
                            finally
                            { getTries++; }
                        }
                    }

答案 1 :(得分:0)

您可以将blob作为流而不是字节数组返回。此处的相关问题中有一个代码示例:Returning Azure BLOB from WCF service as a Stream - Do we need to close it?

请注意,在返回流时可以使用哪些绑定有一些限制。