Chcę serializować obiekty do łańcuchów iz powrotem.
Używamy protobuf-net, aby pomyślnie zamienić obiekt w strumień iz powrotem.
Jednak Stream to string iz powrotem ... nie jest tak skuteczny. Po przejściu przez StreamToString
i StringToStream
, nowy Stream
nie jest deserializowany przez protobuf-net; rodzi Arithmetic Operation resulted in an Overflow
wyjątek. Jeśli zdeserializujemy oryginalny strumień, to zadziała.
Nasze metody:
public static string StreamToString(Stream stream)
{
stream.Position = 0;
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
}
public static Stream StringToStream(string src)
{
byte[] byteArray = Encoding.UTF8.GetBytes(src);
return new MemoryStream(byteArray);
}
Nasz przykładowy kod wykorzystujący te dwa:
MemoryStream stream = new MemoryStream();
Serializer.Serialize<SuperExample>(stream, test);
stream.Position = 0;
string strout = StreamToString(stream);
MemoryStream result = (MemoryStream)StringToStream(strout);
var other = Serializer.Deserialize<SuperExample>(result);
c#
.net
serialization
deserialization
protobuf-net
flipuhdelphia
źródło
źródło
Odpowiedzi:
To jest tak powszechne, ale tak głęboko błędne. Dane protobuf nie są danymi ciągów. Z pewnością nie jest to ASCII. Używasz kodowania wstecz . Transfery kodowania tekstu:
Nie masz „sformatowanych bajtów”. Masz dowolne bajty . Musisz użyć czegoś takiego jak kodowanie base-n (zwykle: base-64). To przenosi
spójrz na Convert.ToBase64String i Convert. FromBase64String
źródło
BinaryFormatter
podobnego do tego dziwnego przykładu ?Właśnie to przetestowałem i działa dobrze.
Jeśli
stream
została już napisana, możesz zechcieć odszukać początek przed pierwszym, zanim przeczytasz tekst:stream.Seek(0, SeekOrigin.Begin);
źródło
konwersja UTF8 MemoryStream na String:
źródło
var array = stream.ToArray(); var str = Encoding.UTF8.GetString(array, 0, array.Length);
. Zobacz także msdn.microsoft.com/en-us/library/…ToArray()
przydziela nową tablicę w pamięci i kopiuje dane z bufora, co może mieć poważne konsekwencje, jeśli masz do czynienia z dużą ilością danych.Podczas testowania spróbuj użyć
UTF8
strumienia Encode, jak poniżejźródło
Spróbuj tego.
źródło
Napisałem użyteczną metodę do wywoływania dowolnej akcji, która przyjmuje a
StreamWriter
i zapisuje ją w postaci ciągu znaków. Metoda jest taka;I możesz tego używać w ten sposób;
Wiem, że można to zrobić o wiele łatwiej za pomocą a
StringBuilder
, chodzi o to, że możesz wywołać każdą metodę, która używaStreamWriter
.źródło
Różni się od innych odpowiedzi, ale najprostszym sposobem na zrobienie tego dokładnie dla większości typów obiektów jest XmlSerializer:
Wszystkie właściwości publiczne obsługiwanych typów zostaną zserializowane. Obsługiwane są nawet niektóre struktury kolekcji, które będą tunelować do właściwości podobiektów. Możesz kontrolować, jak serializacja działa z atrybutami we właściwościach.
Nie działa to ze wszystkimi typami obiektów, niektóre typy danych nie są obsługiwane w przypadku serializacji, ale ogólnie jest dość potężne i nie musisz się martwić o kodowanie.
źródło
W przypadku, gdy chcesz serializować / deserializować POCO, biblioteka JSON Newtonsoft jest naprawdę dobra. Używam go do utrwalania POCO w SQL Server jako ciągi JSON w polu nvarchar. Uwaga: ponieważ nie jest to prawdziwa de / serializacja, nie zachowa prywatnych / chronionych członków i hierarchii klas.
źródło