2013-10-03 16 views
6

Abbiamo un'astrazione del file system che ci consente di passare facilmente dalla memoria locale a quella cloud (Azure).Accoda al flusso CloudBlockBlob

Per i file di lettura e scrittura che abbiamo i seguenti membri:

Stream OpenRead(); 
Stream OpenWrite(); 

Parte della nostra applicazione "fasci" di documenti in un unico file. Per il nostro fornitore di storage locale OpenWrite restituisce un flusso appendable:

public Stream OpenWrite() 
{ 
    return new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, BufferSize, useAsync: true); 
} 

Per l'archiviazione blob Azure facciamo la seguente:

public Stream OpenWrite() 
{    
    return blob.OpenWrite(); 
} 

Purtroppo questo sovrascrive il contenuto di un blob ogni volta. È possibile restituire un flusso scrivibile che può essere aggiunto a?

risposta

5

Sulla base della documentazione per OpenWrite qui http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.blob.cloudblockblob.openwrite.aspx, The OpenWrite method will overwrite an existing blob unless explicitly prevented using the accessCondition parameter.

Una cosa che potreste fare è leggere i dati BLOB in un flusso e tornare quella corrente alla propria applicazione chiamata e lasciare che l'applicazione Aggiunta dati a quel flusso. Ad esempio, vedere il codice qui sotto:

static void BlobStreamTest() 
    { 
     storageAccount = CloudStorageAccount.DevelopmentStorageAccount; 
     CloudBlobContainer container = storageAccount.CreateCloudBlobClient().GetContainerReference("temp"); 
     container.CreateIfNotExists(); 
     CloudBlockBlob blob = container.GetBlockBlobReference("test.txt"); 
     blob.UploadFromStream(new MemoryStream());//Let's just create an empty blob for the sake of demonstration. 
     for (int i = 0; i < 10; i++) 
     { 
      try 
      { 
       using (MemoryStream ms = new MemoryStream()) 
       { 
        blob.DownloadToStream(ms);//Read blob data in a stream. 
        byte[] dataToWrite = Encoding.UTF8.GetBytes("This is line # " + (i + 1) + "\r\n"); 
        ms.Write(dataToWrite, 0, dataToWrite.Length); 
        ms.Position = 0; 
        blob.UploadFromStream(ms); 
       } 
      } 
      catch (StorageException excep) 
      { 
       if (excep.RequestInformation.HttpStatusCode != 404) 
       { 
        throw; 
       } 
      } 
     } 
    } 
+0

Questo è quello che ho finito per fare. L'approccio consigliato sembra essere 'CloudBlockBlob.PutBlock' ma ci affidiamo a una libreria PDF per eseguire il nostro" raggruppamento "che funziona solo con un singolo flusso di input. –

+1

'CloudBlockBlob.PutBlock' è raccomandato perché se il file diventa grande, l'approccio sopra non sarebbe efficiente poiché si scarica l'intero blob e lo si carica nuovamente. Con 'PutBlock' stai caricando solo la parte aggiunta. –

+0

Sì, questo è un grande svantaggio di * sostituire * il blob ogni volta. Tuttavia, come detto, siamo limitati dalla nostra libreria PDF. Potremmo esaminare la memorizzazione nella cache di una copia locale del BLOB se questo diventa un problema. –

0

V'è ora una classe CloudAppendBlob che permette di aggiungere contenuti ad un blob esistente:

var account = CloudStorageAccount.Parse("storage account connectionstring"); 
var client = account.CreateCloudBlobClient(); 
var container = client.GetContainerReference("container name"); 
var blob = container.GetAppendBlobReference("blob name"); 

Nel tuo caso si desidera aggiungere da un flusso:

await blob.AppendFromStreamAsync(new MemoryStream()); 

Ma è possibile aggiungere da testo, matrice di byte, file. Controlla la documentazione.

Problemi correlati