2010-05-18 3 views
18

J'essaie de créer une classe qui contiendra des fonctions de sérialisation/désérialisation d'objets vers/depuis une chaîne. C'est à quoi il ressemble maintenant:Sérialisation et désérialisation binaires sans création de fichiers (via des chaînes)

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éthode serialiseObjet fonctionne bien, mais DeserializeObject ne fonctionne pas. Je reçois toujours une exception avec le message "End of Stream rencontré avant que l'analyse soit terminée". Qu'est-ce qui ne va pas ici?

Répondre

40

Le résultat de la sérialisation d'un objet avec BinaryFormatter est un flux d'octets, pas une chaîne.
Vous ne pouvez pas traiter les octets comme des caractères comme C ou Python.

Encode l'objet sérialisé with Base64 pour obtenir une chaîne à la place:

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

et

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

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

c'est super, merci –

+0

@Pindatjuh: C'est incorrect. Base64 code 6 bits par caractère, ce qui signifie que vous allez générer 8/6 - environ 1,33 - octets de sortie pour chaque octet d'entrée. ASCII encode 7 bits par caractère, ce qui signifie que vous générez 8/7 - environ 1,14 - octets de sortie par octet d'entrée. (En supposant ici, avec optimisme, que vous utilisez la plage complète de 7 bits, utiliser seulement 92 caractères, comme vous le proposez, serait légèrement moins efficace.) – LukeH

0

Utilisez UTF8 Encodage Base64 au lieu de l'ASCII, à la fois pour l'encodage et le décodage.

+1

Pas tous les flux d'octets est un UTF-8 valide chaîne codée. – dtb

+0

Bonne prise; vous avez raison. –

Questions connexes