2012-06-05 22 views
12

Estoy intentando descargar un archivo de cloudBlob a través de la transmisión. Me refiero a este artículo CloudBlobCloudBlob.DownloadToStream devuelve nulo

Este es el código para descargar la burbuja

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

Y el código para convertirlo en el conjunto de bytes

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

Pero siempre me dan valor nulo. A continuación se muestra el contenido del archivo de transmisión.

enter image description here

Qué hay de malo en esto? Por favor ayuda.

EDITAR

Ajuste de la posición a 0 en el interior ReadFully método no está permitido, así que lo puse en el interior DownloadBlobAsStream

Esto debería funcionar ahora:

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

hay un malentendido de su parte como seguro que puede fijar la posición de 0 @ ReadFully sin embargo es necesario utilizar el objeto de "entrada". Object mem tiene alcance local dentro de DownloadBlobAsStream() por eso, si desea establecer mem.Position debe hacerlo en esta función; sin embargo, cuando llama a ReadFully() y pasa su objeto "Stream", puede establecer su posición en 0 como bueno, como mostré en mi publicación. Entonces ambos son aceptados y funcionarán. – AvkashChauhan

+0

Si configuro Position = 0 dentro de ReadFully, arroja un error "No admitido", y cuando trato de ver la propiedad de entrada, 'CanSeek = false' pero su idea ayudó mucho. :) – fiberOptics

+0

¿Solo para aclarar está obteniendo un valor nulo o una matriz de bytes vacía? No he visto un valor nulo, pero he visto una matriz de bytes vacía en mis pruebas sin cambiar de ninguna forma la posición de la secuencia. – kendaleiv

Respuesta

12

Su problema es que su el puntero de la corriente de entrada está ajustado al final del vapor (vea la captura de pantalla, Longitud y Posición ambos muestran el mismo valor) por eso, cuando lo lee, siempre obtiene nulo. Lo que se necesita para establecer a puntero del flujo de entrada a 0 usando Stream.Position = 0 de la siguiente manera:

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

Entonces, ¿esto implica que DownloadToStream en realidad no cumple con su promesa? ¿Que en lugar de permitir que un usuario realmente transmita los datos de azul, simplemente está haciendo casi lo mismo que DownloadByteArray ya que te obliga a leer todo el archivo en la memoria? –

+3

Creo que CloudBlockBlob.OpenRead() se puede usar para obtener una secuencia que se puede usar para acceder a partes del blob sin tener que descargar todo en primer lugar. – user764754

5

Cómo sobre el uso del método OpenRead() en el objeto CloudBlob?

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

He tratado de implementar el código anterior, pero para mi sorpresa, la función GetBlockBlobReference no estaba presente en CloudBlobClient pero en CloudBlockBlob.

Quizás las DLL hayan cambiado a través del tiempo.

Por lo tanto les presento mi adaptación:

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


} 
Cuestiones relacionadas