2012-06-05 43 views
12

ストリーム経由でcloudBlobからファイルをダウンロードしようとしています。私はここでCloudBlobCloudBlob.DownloadToStreamがnullを返します

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

とバイト配列

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

に変換しかし、私は常にnull値を取得するためのコードブロブをダウンロードするためのコードで、この記事を参照してください。以下はストリームファイルの内容です。

enter image description here

はこれで何が間違っているのですか?助けてください。 ReadFullyメソッド内で0に位置の設定

EDIT

が許可されていないので、私はDownloadBlobAsStream

内に置くこれは動作するはずです:

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; 
} 
+0

あなたが「入力」オブジェクトを使用する必要があります、しかし、あなたは確認のreadFully @ 0に位置を設定することができますようあなたの部分にいくつかの誤解があります。 Object memはDownloadBlobAsStream()内にローカルスコープを持っています。なぜなら、mem.Positionを設定する必要があるのは、この関数で行う必要がありますが、ReadFully()を呼び出して "Stream"オブジェクトを渡すとき、Positionを0まあ、私は私の投稿に示したように。両方とも受け入れられ、うまくいくでしょう。 – AvkashChauhan

+0

ReadFullyの中にPosition = 0を設定すると、「サポートされていません」というエラーがスローされ、入力プロパティを調べようとすると、CanSeek = falseと表示されますが、 :) – fiberOptics

+0

ちょうど明確にするには、null値または空のバイト配列を取得していますか?私はnull値を見たことはありませんが、私のテストでは何もストリームの位置を変更せずに空のバイト配列を見てきました。 – kendaleiv

答えて

12

あなたの問題があることは、あなたの入力ストリームポインタが蒸気の終わりに設定されています(スクリーンショットを参照してください、LengthとPositionの両方が同じ値を示しています)。あなたは以下のようにStream.Position = 0を使用して0に入力ストリームポインタに設定する必要があります:

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(); 
    } 
} 
+2

これは、実際にはDownloadToStreamが約束どおりに実行されていないことを意味していますか?これは、ユーザーが本当にAzureからデータをストリーミングできるようにするのではなく、ファイル全体をメモリに読み込むように強制しているだけなので、DownloadByteArrayとほぼ同じことをやっています。 –

+3

私はCloudBlockBlobを考えます。OpenRead()は、まず全体をダウンロードすることなく、BLOBの一部にアクセスするために使用できるストリームを取得するために使用できます。 – user764754

5

方法CloudBlobオブジェクトにOpenRead()メソッドを使用してはどうですか?

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

私は上記のコードを実行しようとしているが、私の驚きに、機能GetBlockBlobReferenceCloudBlobClientではなくCloudBlockBlobには存在しませんでした。

DLLが時間によって変化している可能性があります。

ので、私は私の適応を提示:

public class BlobStorageHelper 
{ 
    private readonly CloudBlobClient _blobClient; 
    protected readonly CloudStorageAccount StorageAccount; 
    public string _containerName { get; set; } 

    public BlobStorageHelper() 

    { 
     _blobClient = base.StorageAccount.CreateCloudBlobClient(); 
     _containerName = ConfigurationManager.AppSettings["StorageContainerName"]; 
     StorageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnectionString"]); 
    } 

    protected Stream DownloadBlobAsStream(string blobUri) 
    { 
     CloudStorageAccount account = this.StorageAccount; 
     CloudBlockBlob blob = GetBlockBlobReference(account, blobUri); 

     Stream mem = new MemoryStream(); 
     if (blob != null) 
     { 
      blob.DownloadToStream(mem);     
     } 

     return mem; 
    } 

    private CloudBlockBlob GetBlockBlobReference(CloudStorageAccount account, string blobUri) 
    { 
     string blobName = blobUri.Substring(blobUri.IndexOf("/" + _containerName + "/")).Replace("/" + _containerName + "/", ""); 
     CloudBlobClient blobclient = account.CreateCloudBlobClient(); 
     CloudBlobContainer container = _blobClient.GetContainerReference(_containerName); 
     container.CreateIfNotExists(); 
     CloudBlockBlob blob = container.GetBlockBlobReference(blobName); 
     return blob; 
    } 


    public byte[] DownloadBlobAsByeArray(string blobUri) 
    { 
     Stream inputStream = DownloadBlobAsStream(blobUri); 

     byte[] buffer = new byte[16 * 1024]; 

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

     using (MemoryStream ms = new MemoryStream()) 
     { 
      int read; 
      while ((read = inputStream.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       ms.Write(buffer, 0, read); 
      } 
      return ms.ToArray(); 
     } 
    } 


} 
関連する問題