2010-05-18 9 views
18

Estoy intentando crear una clase que contendrá funciones para serializar/deserializar objetos a/desde cadenas. Eso es lo que parece ahora:serialización binaria y deserialización sin crear archivos (a través de cadenas)

public class BinarySerialization 
    { 
     public static string SerializeObject(object o) 
     { 
      string result = ""; 

      if ((o.GetType().Attributes & TypeAttributes.Serializable) == TypeAttributes.Serializable) 
      { 
       BinaryFormatter f = new BinaryFormatter(); 
       using (MemoryStream str = new MemoryStream()) 
       { 
        f.Serialize(str, o); 
        str.Position = 0; 

        StreamReader reader = new StreamReader(str); 
        result = reader.ReadToEnd(); 
       } 
      } 

      return result; 
     } 

     public static object DeserializeObject(string str) 
     { 
      object result = null; 

      byte[] bytes = System.Text.Encoding.ASCII.GetBytes(str); 
      using (MemoryStream stream = new MemoryStream(bytes)) 
      { 
       BinaryFormatter bf = new BinaryFormatter(); 
       result = bf.Deserialize(stream); 
      } 

      return result; 
     } 
    } 

método SerializeObject funciona bien, pero DeserializeObject no. Siempre recibo una excepción con el mensaje "End of Stream encontrado antes de que se completara el análisis". ¿Qué puede estar mal aquí?

Respuesta

40

El resultado de serializar un objeto con BinaryFormatter es una secuencia de octetos, no una cadena.
No puedes tratar los bytes como caracteres como C o Python.

codificar el objeto serializado with Base64 para obtener una cadena en lugar:

public static string SerializeObject(object o) 
{ 
    if (!o.GetType().IsSerializable) 
    { 
     return null; 
    } 

    using (MemoryStream stream = new MemoryStream()) 
    { 
     new BinaryFormatter().Serialize(stream, o); 
     return Convert.ToBase64String(stream.ToArray()); 
    } 
} 

y

public static object DeserializeObject(string str) 
{ 
    byte[] bytes = Convert.FromBase64String(str); 

    using (MemoryStream stream = new MemoryStream(bytes)) 
    { 
     return new BinaryFormatter().Deserialize(stream); 
    } 
} 
+0

eso es genial, gracias –

+0

@Pindatjuh: Eso es incorrecto. Base64 codifica 6 bits por carácter, lo que significa que generará 8/6, aproximadamente 1,33 bytes de salida por cada byte de entrada. ASCII codifica 7 bits por carácter, lo que significa que generará 8/7, aproximadamente 1.14, bytes de salida por byte de entrada. (Supongamos aquí, de manera optimista, que está utilizando el rango completo de 7 bits. Usar solo 92 caracteres, como propone, sería un poco menos eficiente). – LukeH

0

Use UTF8 Codificación de Base64 en lugar de ASCII, tanto para la codificación como para la decodificación.

+1

No todas las corrientes del octeto es una cadena codificada en UTF-8 válidos. – dtb

+0

Buena captura; estás en lo correcto. –

Cuestiones relacionadas