2012-02-05 10 views
0

ブラブ(潜在的に1GB)をオフセットとしてbyte[]としてダウンロードして、Silverlightアプリケーションで使用できるWCFサービスを提供するよう依頼されました。本質的に、操作には、オフセットするバイト数と返すバイトの最大数のパラメータがあります。何も複雑ではないと思います。WCFを使用してチャンク内のAzureブロブをダウンロードする

私がこれまで持っているコードは次のとおりです。

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

私は(比較的小さなファイル< 2メガバイトとはいえ)これをテストしてきたし、それが作業を行いますが、私の質問は以下のとおりです。

  • ことができる人コードの改善を提案しますか?
  • 要件を満たした方がよいでしょうか?

答えて

0

blobをバイト配列ではなくストリームとして返すことができます。ここに関連する質問にコードサンプルがあります。Returning Azure BLOB from WCF service as a Stream - Do we need to close it?

ストリームを返すときに使用できるバインディングにはいくつかの制限があります。

+0

前述のとおり、ブロブをストリームではなくバイト[]チャンクで返す必要があります。それとも私はあなたが何を意味するのか誤解しましたか? – Digbyswift

+0

なぜストリームの代わりにバイト配列としてBLOBを消費する必要がありますか? –

+0

私はしません。私のクライアントがこれを要求しました。おそらく彼らはすでにこれを必要とする解決策を用意しています。私は、同じセッションではなく、部分的にブロブをダウンロードする柔軟性が欲しいと思います。 – Digbyswift

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++; } 
         } 
        } 
関連する問題