2010-05-18 19 views
18

Ich versuche, eine Klasse zu erstellen, die Funktionen zum Serialisieren/Deserialisieren von Objekten zu/von Zeichenfolge enthalten wird. Das ist, was es sieht aus wie jetzt:Binäre Serialisierung und Deserialisierung ohne Erstellen von Dateien (über Zeichenfolgen)

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

SerializeObject Methode funktioniert gut, aber DeserializeObject nicht. Ich bekomme immer eine Ausnahme mit der Nachricht "End of Stream vor dem Parsen war abgeschlossen". Was kann hier falsch sein?

Antwort

40

Das Ergebnis der Serialisierung eines Objekts mit BinaryFormatter ist ein Oktettstrom, keine Zeichenfolge.
Sie können die Bytes nicht einfach als Zeichen wie in C oder Python behandeln.

Encode das serialisierte Objekt with Base64 stattdessen einen String zu erhalten:

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

und

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

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

das ist toll, danke –

+0

@Pindatjuh: Das ist falsch. Base64 codiert 6 Bits pro Zeichen, was bedeutet, dass Sie 8/6 - ca. 1,33 - Bytes Ausgabe für jedes Byte der Eingabe generieren. ASCII codiert 7 Bits pro Zeichen, was bedeutet, dass Sie 8/7 - ca. 1,14 - Ausgangsbytes pro Eingangsbyte generieren. (Angenommen, Sie verwenden hier optimistisch den vollen 7-Bit-Bereich. Die Verwendung von nur 92 Zeichen wäre, wie Sie vorschlagen, etwas weniger effizient.) – LukeH

0

Verwenden Sie UTF8 Base64-Codierung statt ASCII, sowohl für die Codierung und Decodierung.

+1

Nicht jeder Oktett-Stream ist ein gültiger UTF-8 kodierten String. – dtb

+0

Guter Fang; Du hast Recht. –

Verwandte Themen