Quiero serializar objetos en cadenas y viceversa.
Utilizamos protobuf-net para convertir un objeto en Stream y viceversa, con éxito.
Sin embargo, Transmitir a cadena y viceversa ... no tan exitoso. Después de pasar StreamToString
y StringToStream
, lo nuevo Stream
no es deserializado por protobuf-net; plantea una Arithmetic Operation resulted in an Overflow
excepción. Si deserializamos la secuencia original, funciona.
Nuestros métodos:
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);
}
Nuestro código de ejemplo usando estos dos:
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
fuente
fuente
Respuestas:
Esto es tan común pero tan profundamente equivocado. Los datos de Protobuf no son datos de cadena. Ciertamente no es ASCII. Estás utilizando la codificación al revés . Una codificación de texto transfiere:
No tiene "bytes formateados". Tienes bytes arbitrarios . Necesita usar algo como una codificación base-n (comúnmente: base-64). Esto transfiere
mira Convert.ToBase64String y Convert. FromBase64String
fuente
BinaryFormatter
similar a este extraño ?Acabo de probar esto y funciona bien.
Si
stream
ya se ha escrito, es posible que desee buscar el principio antes del primero antes de leer el texto:stream.Seek(0, SeekOrigin.Begin);
fuente
una conversión de UTF8 MemoryStream a String:
fuente
var array = stream.ToArray(); var str = Encoding.UTF8.GetString(array, 0, array.Length);
. Ver también msdn.microsoft.com/en-us/library/…ToArray()
asigna una nueva matriz en la memoria y copia los datos del búfer, lo que puede tener serias implicaciones si se trata de una gran cantidad de datos.Cuando realice la prueba, intente con la
UTF8
secuencia Encode como se muestra a continuaciónfuente
Prueba esto.
fuente
Escribí un método útil para llamar a cualquier acción que tome una
StreamWriter
y escribirla en una cadena. El método es así;Y puedes usarlo así;
Sé que esto se puede hacer mucho más fácil con a
StringBuilder
, el punto es que puedes llamar a cualquier método que requiera aStreamWriter
.fuente
Diferente de las otras respuestas, pero la forma más directa de hacer exactamente eso para la mayoría de los tipos de objetos es XmlSerializer:
Todas sus propiedades públicas de los tipos admitidos serán serializadas. Incluso algunas estructuras de colección son compatibles, y se canalizarán a propiedades de subobjeto. Puede controlar cómo funciona la serialización con atributos en sus propiedades.
Esto no funciona con todos los tipos de objetos, algunos tipos de datos no son compatibles con la serialización, pero en general es bastante potente y no tiene que preocuparse por la codificación.
fuente
En caso de que desee serializar / deserializar POCO, la biblioteca JSON de Newtonsoft es realmente buena. Lo uso para persistir POCO dentro de SQL Server como cadenas JSON en un campo nvarchar. La advertencia es que, dado que no es una deserialización / serialización verdadera, no conservará los miembros privados / protegidos ni la jerarquía de clases.
fuente