it-swarm.com.de

Was sind die Unterschiede zwischen XmlSerializer und BinaryFormatter?

Ich habe letzte Woche viel Zeit mit der Serialisierung verbracht. In dieser Zeit habe ich viele Beispiele gefunden, die entweder den BinaryFormatter oder den XmlSerializer verwenden. Leider fand ich keine Beispiele, die die Unterschiede zwischen den beiden ausführlich erläuterten.

Der Ursprung meiner Neugier liegt darin, warum der BinaryFormatter in der Lage ist, direkt zu einer Schnittstelle zu deserialisieren, während der XmlSerializer dies nicht tut. Jon Skeet in einer Antwort auf " Casting auf mehrere (unbekannte Typen) zur Laufzeit " enthält ein Beispiel für die direkte binäre Serialisierung einer Schnittstelle. Stan R. stellte mir die Mittel zur Verfügung, um mein Ziel mithilfe des XmlSerializers in seiner Antwort auf " XML ​​Object Deserialization to Interface " zu erreichen.

Neben den offensichtlichen Aspekten des BinaryFormatter wird die binäre Serialisierung verwendet, während der XmlSerializer XML verwendet. Ich möchte die grundlegenden Unterschiede besser verstehen. Wann man das eine oder das andere nutzt und die Vor- und Nachteile eines jeden.

48
ahsteele

Der Grund, warum ein binärer Formatierer in der Lage ist, direkt zu einem Schnittstellentyp zu deserialisieren, liegt darin, dass bei der Serialisierung eines Objekts in einen binären Datenstrom Metadaten mit dem Typ und Assembly-Informationen in die Objektdaten eingefügt werden. Das heißt, wenn der binäre Formatierer das Objekt deserialisiert, dem er den Typ kennt, das richtige Objekt erstellt, können Sie das in einen Schnittstellentyp umwandeln, den das Objekt implementiert. 

Der XML-Serialisierer auf der anderen Seite serialisiert nur zu einem Schema und serialisiert nur die öffentlichen Felder und Werte des Objekts und keine anderen Typinformationen als diese (z. B. Schnittstellen, die den Typ implementieren).

Hier ist ein guter Beitrag, .NET-Serialisierung , der Vergleich von BinaryFormatter , SoapFormatter und XmlSerializer . Ich empfehle Ihnen, sich die folgende Tabelle anzusehen, die zusätzlich zu den zuvor genannten Serialisierern den DataContractSerializer , NetDataContractSerializer und protobuf-net enthält.

Serialization Comparison

91
Dustin Hodges

Nur um zu wiegen ...

Der offensichtliche Unterschied zwischen den beiden ist "binary vs xml", geht aber viel tiefer als das:

  • felder (BinaryFormatter = bf) vs. public -Mitglieder (normalerweise Eigenschaften) (XmlSerializer = xs)
  • typ-Metadaten-basiert (bf) vs. vertragsbasiert (xs)
  • version spröde (bf) vs. versionstolerant (xs)
  • "graph" (bf) vs "tree" (xs)
  • .NET-spezifisch (bf) vs. portabel (xs)
  • undurchsichtig (bf) vs. lesbar (xs)

Als eine Diskussion darüber, warum BinaryFormatter spröde sein kann, siehe hier .

Es ist unmöglich zu diskutieren, was größer ist. Alle Typmetadaten in BinaryFormatter können sie vergrößern. Und XmlSerializer kann sehr gut mit Komprimierung arbeiten wie gzip.

Es ist jedoch möglich, die Stärken von jedem zu nehmen; Google hat beispielsweise ein eigenes Datenserialisierungsformat ("Protokollpuffer") aus der Open-Source-Umgebung bereitgestellt. Das ist:

  • vertraglich
  • tragbar (siehe Liste der Implementierungen )
  • versionstolerant
  • baumbasiert
  • undurchsichtig (obwohl es Werkzeuge gibt, um Daten anzuzeigen, wenn sie mit einem .proto kombiniert werden)
  • normalerweise " contract first ", aber einige Implementierungen erlauben implizite Verträge, die auf Reflektion basieren

Es ist jedoch wichtig, dass diese Daten sehr dicht sind (keine Typ-Metadaten, reine Binärdarstellung, kurze Tags, Tricks wie Basis-7-Codierung mit variabler Länge) und sehr effizient zu verarbeiten sind (keine komplexe XML-Struktur, keine zu Mitgliedern passenden Zeichenfolgen usw. ).

Ich könnte etwas voreingenommen sein. Ich pflege eine der Implementierungen (einschließlich einiger für C # /. NET geeigneten), aber Sie werden feststellen, dass ich nicht verknüpft mit any spezifischer Implementierung; das Format steht unter seinen eigenen Verdiensten ;-p

6
Marc Gravell

Der XML-Serializer erzeugt (implizit) XML und auch ein XML-Schema. Es wird XML erzeugen, das diesem Schema entspricht.

Eine Folge ist, dass nichts serialisiert wird, was nicht im XML-Schema beschrieben werden kann. Zum Beispiel gibt es keine Möglichkeit, zwischen einer Liste und einem Array im XML-Schema zu unterscheiden, sodass das vom Serialisierer erzeugte XML-Schema auf beide Arten interpretiert werden kann.

Die Laufzeit-Serialisierung (zu der der BinaryFormatter gehört) serialisiert die tatsächlichen .NET-Typen auf der anderen Seite. Wenn Sie also einen List<int> senden, erhält die andere Seite einen List<int>.

Das funktioniert natürlich besser, wenn auf der anderen Seite .NET läuft.

2
John Saunders

Der XmlSerializer serialisiert den Typ, indem er alle Eigenschaften des Typs liest, die sowohl einen öffentlichen Getter als auch einen öffentlichen Setter (und auch öffentliche Felder) enthalten. In diesem Sinne serialisiert/deserialisiert der XmlSerializer die "öffentliche Ansicht" der Instanz.

Im Gegensatz dazu serialisiert der binäre Formatierer einen Typ, indem er die "internen Elemente" der Instanz, d. H. Ihre Felder, serialisiert. Alle Felder, die nicht als [Nicht serialisiert] gekennzeichnet sind, werden in den Binärstrom serialisiert. Der Typ selbst muss als [Serializable] markiert sein, ebenso wie alle internen Felder, die auch serialisiert werden sollen.

1
Rob Levine

Ich denke, eine der wichtigsten ist, dass die binäre Serialisierung sowohl öffentliche als auch private Mitglieder serialisieren kann, während der andere nur mit öffentlichen Mitgliedern arbeitet. 

Hier bietet es einen sehr hilfreichen Vergleich zwischen diesen beiden Größen. Dies ist ein sehr wichtiges Problem, da Sie Ihr serialisiertes Objekt möglicherweise an einen Remote-Computer senden.

http://www.nablasoft.com/alkampfer/index.php/2008/10/31/binary-versus-xml-serialization-size/

0
paradisonoir