2010-05-18 13 views
18

Sto provando a creare una classe che conterrà funzioni per serializzare/deserializzare oggetti da/per stringa. Questo è quello che sembra ora:Serializzazione e deserializzazione binaria senza creare file (tramite stringhe)

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; 
     } 
    } 

metodo SerializeObject funziona bene, ma non lo fa DeserializeObject. Ricevo sempre un'eccezione con il messaggio "Fine del flusso rilevato prima del completamento dell'analisi". Cosa potrebbe esserci di sbagliato qui?

risposta

40

Il risultato della serializzazione di un oggetto con BinaryFormatter è un flusso di ottetto, non una stringa.
Non puoi semplicemente trattare i byte come caratteri come in C o Python.

Codifica l'oggetto serializzato with Base64 per ottenere una stringa invece:

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()); 
    } 
} 

e

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

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

è fantastico, grazie –

+0

@Pindatjuh: non è corretto. Base64 codifica 6 bit per carattere, il che significa che genererai 8/6 - circa 1,33 - byte di output per ogni byte di input. ASCII codifica 7 bit per carattere, il che significa che genererai 8/7 - circa 1,14 - byte di output per byte di input. (Supponendo qui, ottimisticamente, che stai utilizzando l'intera gamma a 7 bit. L'utilizzo di soli 92 caratteri, come proposto, sarebbe leggermente meno efficiente). – LukeH

0

Utilizzare UTF8 Codifica Base64 anziché ASCII, sia per la codifica che per la decodifica.

+1

Non ogni ottetto flusso è un UTF-8 stringa codificata valida. – dtb

+0

Buona cattura; hai ragione. –

Problemi correlati