2012-04-23 22 views
5

Używam PutBlock i PutBlockList przesłać dane do blob bloku, kod używam tego jest poniżej: -Pisanie do Azure bloku Blobs

CloudBlobContainer container = blobStorage.GetContainerReference("devicebackups"); 
var permissions = container.GetPermissions(); 
permissions.PublicAccess = BlobContainerPublicAccessType.Container; 
container.SetPermissions(permissions); 
CloudBlockBlob blob = container.GetBlockBlobReference(serialNo.ToLower() + " " + dicMonths[DateTime.Now.Month]); 
try 
{ 
    var serializer = new XmlSerializer(typeof(List<EnergyData>)); 
    var stringBuilder = new StringBuilder(); 
    using (XmlWriter writer = XmlWriter.Create(stringBuilder)) 
    { 
     try 
     { 
      serializer.Serialize(writer, deviceData); 
      byte[] byteArray = Encoding.UTF8.GetBytes(stringBuilder.ToString()); 

      List<string> blockIds = new List<string>(); 
      try 
      { 
       blockIds.AddRange(blob.DownloadBlockList(BlockListingFilter.Committed).Select(b => b.Name)); 
      } 
      catch (StorageClientException e) 
      { 
       if (e.ErrorCode != StorageErrorCode.BlobNotFound) 
       { 
        throw; 
       } 
       blob.Container.CreateIfNotExist(); 
      } 
      var newId = Convert.ToBase64String(Encoding.UTF8.GetBytes(blockIds.Count().ToString())); 
      blob.PutBlock(newId, new MemoryStream(byteArray), null); 
      blockIds.Add(newId); 
      blob.PutBlockList(blockIds); 
     } 
     catch (Exception ex) 
     { 
      UT.ExceptionReporting(ex, "Error in Updating Backup Blob - writing byte array to blob"); 
     } 
    } 
} 
catch (Exception ex) 
{ 
    UT.ExceptionReporting(ex, "Error in Updating Backup Blob - creating XmlWriter"); 
} 
} 
catch (Exception ex) 
{ 
    UT.ExceptionReporting(ex, "Error in Updating Backup Blob - getting container and blob references, serial no -" + serialNo); 
} 

To działa na 10 bloków, a następnie na 11 blokuje awarię z następującym błędem: -

StorageClientException - podana lista bloków jest nieprawidłowa.

InnerException = {"The remote server returned an error: (400) Bad Request."} 

Przeszukałem internet w poszukiwaniu zgłoszeń o tym samym błędzie, ale nie miałem szczęścia.

Każda pomoc będzie mile widziana.

+1

Z ciekawości, z jakiejkolwiek przyczyny, po prostu używasz strumienia, aby przesłać go do obszaru blob? – BrentDaCodeMonkey

+0

Czy używasz tego kodu w emulatorze lub na prawdziwym koncie pamięci masowej? –

+0

brakuje ci 'try {' na początku, ponieważ masz '} catch' po całym kodzie w nawiasach –

Odpowiedz

14

For a given blob, the length of the value specified for the blockid parameter must be the same size for each block.

http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx

10 pierwszych bloków są ponumerowane liczbami od 0 do 9. 11. Blok jest numerem 10, która jest większa o jeden znak. Dlatego powinieneś zmienić swój schemat numeracji, aby zawsze używać tej samej długości. Jednym z rozwiązań byłoby przeliczenie liczby na łańcuch o zerowym napięciu, który jest wystarczająco długi, aby pomieścić liczbę bloków, które można mieć.

Ale jeśli nie potrzebujesz korzyści płynących z używania bloków, prawdopodobnie lepiej będzie po prostu napisać cały blob jednym ruchem zamiast użyć bloków.

+0

Dzięki za odpowiedź breischl, użyłem skonwertowanej długości ciągu do porównania identyfikatorów blokowych. Potrzebuję funkcji blokowania, ponieważ nie mam wszystkich danych w tym samym czasie. Wdrażę to dzisiaj i dam ci znać, jak to działa. Dzięki jeszcze raz. – ChrisW

+0

To sprawiło przyjemność, dziękuję! – ChrisW

2

Ustaw blockID ma poniżej kod

var blockIdBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(blockId.ToString(CultureInfo.InvariantCulture).PadLeft(32, '0'))); 
0

Moim problemem było to, że po 10 bloku put otrzymałem złe żądanie (Error 400).

  1. zastąpiona Encoding.UTF8.GetBytes z System.BitConverter.GetBytesstring blockIdBase64=Convert.ToBase64String(System.BitConverter.GetBytes(x++)); blockIDs muszą być tej samej wielkości. BitConverter.GetBytes wykonuje pracę .
  2. Nadal otrzymałem złe żądanie (Error 400). Rozwiązałem go przez usuwanie temp blob za pomocą "Eksploratora pamięci Azure". To jest jak resetowanie tymczasowego bloku z moich poprzednich złych prób.