2011-08-01 9 views
18

Chciałbym serializować/dekompilować obiekt za pomocą ciągu. Po prostu, aby zauważyć, kiedy serializować/dekompilować do pliku wszystko działa dobrze. Co próbuję zrobić, to uzyskać ciąg znaków, aby móc go zapisać w bazie danych, a następnie wyciągnąć go później, aby zdekresować.protobuf-net Serialize na ciąg i przechowywanie w bazie danych Następnie De Serialize

Oto kod, który działa:

MemoryStream msTest = new MemoryStream(); 
Serializer.Serialize(msTest, registrationBlocks); 
msTest.Position = 0; 
List<RVRegistrationBlock> CopiedBlocks = new List<RVRegistrationBlock>(); 
CopiedBlocks = Serializer.Deserialize<List<RVRegistrationBlock>>(msTest); 

W „CopiedBlocks” przedmiotem jest ta sama lista, która była w „registrationBlocks” Działa świetnie, wszystko w odcinkach/de-odcinkach. Przechowuję tutaj wszystko w strumieniach.

Oto kod, który nie działa, gdy próbuję uzyskać ciąg uczestniczące:

MemoryStream msTestString = new MemoryStream(); 
Serializer.Serialize(msTestString, registrationBlocks); 


msTestString.Position = 0; 
StreamReader srRegBlock = new StreamReader(msTestString); 

byte[] bytedata64 = System.Text.Encoding.Default.GetBytes(srRegBlock.ReadToEnd()); 

string stringBase64 = Convert.ToBase64String(bytedata64); 

byte[] byteAfter64 = Convert.FromBase64String(stringBase64); 
MemoryStream afterStream = new MemoryStream(byteAfter64); 


List<RVRegistrationBlock> CopiedBlocksString = new List<RVRegistrationBlock>(); 
CopiedBlocksString = Serializer.Deserialize<List<RVRegistrationBlock>>(afterStream); 

w ostatnim wierszu, gdy idzie do deserializowania, otrzymuję wyjątek: wyjątek typu „Protobuf. ProtoException "został rzucony. Nie mogę do niego wiercić, wewnętrzny wyjątek jest pusty. Nie mogę zrozumieć, dlaczego to robi.

Zdecydowanie zawęziłem to do faktu, że gdy dostaję ciąg znaków, powoduje to drżenie. Przechowuję ciąg w bazie danych w nvarchar (max), dlatego chcę ciąg znaków.

Każda pomoc będzie bardzo ceniona!

Odpowiedz

24

jestem trochę zagubiony przez korzystanie z StreamReader w tym kontekście wydaje mi się, że można pominąć, że i zrobić coś jak poniżej, aby upewnić się, że nie jest jednokierunkowa Kodowanie dzieje ..

MemoryStream msTestString = new MemoryStream(); 
Serializer.Serialize(msTestString, registrationBlocks); 

string stringBase64 = Convert.ToBase64String(msTestString.ToArray()); 

byte[] byteAfter64 = Convert.FromBase64String(stringBase64); 
MemoryStream afterStream = new MemoryStream(byteAfter64); 

List<RVRegistrationBlock> CopiedBlocksString = new List<RVRegistrationBlock>(); 
CopiedBlocksString = Serializer.Deserialize<List<RVRegistrationBlock>>(afterStream); 
+11

Dobra odpowiedź; istnieje * niewielka * optymalizacja, którą możesz wykonać, jeśli chcesz - 'Convert.ToBase64String (msTestString.GetBuffer(), 0, (int) msTestString.Length)' który unika tworzenia dodatkowego 'byte []'. Ale zadziała "jak jest". –

1

oparciu o odpowiedź i komentarz, używam tych:

 internal static string SerializeToString_PB<T>(this T obj) 
     { 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       ProtoBuf.Serializer.Serialize(ms, obj); 
       return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length); 
      } 
     } 
     internal static T DeserializeFromString_PB<T>(this string txt) 
     { 
      byte[] arr = Convert.FromBase64String(txt); 
      using (MemoryStream ms = new MemoryStream(arr)) 
       return ProtoBuf.Serializer.Deserialize<T>(ms); 
     }