Wat zijn de verschillen tussen de XmlSerializer en BinaryFormatter

Ik heb vorige week een groot deel van mijn tijd besteed aan serialisatie. Gedurende die tijd vond ik veel voorbeelden die gebruik maakten van de BinaryFormatter of XmlSerializer. Helaas heb ik geen voorbeelden gevonden die de verschillen tussen de twee uitgebreid beschrijven.

Het ontstaan ​​van mijn nieuwsgierigheid ligt in waarom de BinaryFormatter in staat is om direct naar een interface te deserialiseren, terwijl de XmlSerializer dat niet is. Jon Skeetin een antwoord op “casting naar meerdere (onbekende typen) tijdens runtime” biedt een voorbeeld van directe binaire serialisatie naar een interface. Stan R.gaf me de middelen om mijn doel te bereiken met behulp van de XmlSerializer in zijn antwoord op “Deserialisatie van XML-objecten naar interface.”

Buiten het voor de hand liggende gebruik van BinaryFormatter, wordt binaire serialisatie gebruikt, terwijl XmlSerializer XML gebruikt. Ik zou graag de fundamentele verschillen beter begrijpen. Wanneer de een of de ander te gebruiken en de voor- en nadelen van elk.


Antwoord 1, autoriteit 100%

De reden dat een binaire formatter rechtstreeks naar een interfacetype kan deserialiseren, is omdat wanneer een object oorspronkelijk is geserialiseerd naar een binaire stroom, metagegevens met type- en assemblagegegevens vastzitten in de objectgegevens. Dit betekent dat wanneer de binaire formatter het object deserialiseert, hij zijn type kent, het juiste object bouwt en u dat vervolgens kunt casten naar een interfacetype dat door het object wordt geïmplementeerd.

De XML-serializer daarentegen serialiseert alleen naar een schema en serialiseert alleen de openbare velden en waarden van het object en geen andere type-informatie (bijv. interfaces die het type implementeert).

Hier is een goede post, .NET Serialization, waarin de BinaryFormatter, SoapFormatteren XmlSerializer. Ik raad u aan naar de volgende tabel te kijken die naast de eerder genoemde serializers de DataContractSerializer, NetDataContractSerializeren protobuf-net.


Antwoord 2, autoriteit 6%

Gewoon om te wegen…

Het voor de hand liggende verschil tussen de twee is “binair versus xml”, maar het gaat veel dieper dan dat:

  • velden (BinaryFormatter=bf) vs openbareleden (meestal eigenschappen) (XmlSerializer=xs)
  • op type metadata gebaseerd (bf) versus contractgebaseerd (xs)
  • version-brittle (bf) versus versie-tolerant (xs)
  • “grafiek” (bf) vs “boom” (xs)
  • .NET specifiek (bf) vs draagbaar (xs)
  • ondoorzichtig (bf) vs door mensen leesbaar (xs)

Als een bespreking van waarom BinaryFormatterbroos kan zijn, zie hier.

Het is onmogelijk om te bespreken welke groter is; alle type metadata in BinaryFormatterkunnen het groter maken. En XmlSerializerkan heel goed werken met compressie zoals gzip.

Het is echter mogelijk om de sterke punten van elk te gebruiken; Google heeft bijvoorbeeld hun eigen gegevensserialisatie-indeling, ‘protocolbuffers’, open source gemaakt. Dit is:

  • op contractbasis
  • draagbaar (zie lijst met implementaties)
  • versie-tolerant
  • op bomen gebaseerd
  • ondoorzichtig (hoewel er tools zijn om gegevens te tonen in combinatie met een .proto)
  • meestal “contract eerst“, maar bij sommige implementaties zijn impliciete contracten toegestaan gebaseerd op reflectie

Maar het belangrijkste is dat het zeer dichte gegevens zijn (geen type-metagegevens, puur binaire weergave, korte tags, trucs zoals variant-length base-7-codering) en zeer efficiënt te verwerken (geen complexe XML-structuur, geen strings om aan te passen aan leden, enz.).

Ik ben misschien een beetje bevooroordeeld; Ik onderhoud een van de implementaties (waaronder een aantal die geschikt zijn voor C#/.NET), maar u zult merken dat ik dat niet heb gedaan
gekoppeld aan elkespecifieke implementatie; het formaat staat op zichzelf ;-p


Antwoord 3, autoriteit 2%

De XML Serializer produceert XML en ook een XML Schema (impliciet). Het zal XML produceren die voldoet aan dit schema.

Een implicatie is dat het niets zal serialiseren dat niet kan worden beschreven in XML Schema. Er is bijvoorbeeld geen manier om onderscheid te maken tussen een lijst en een array in XML Schema, dus het XML Schema geproduceerd door de serializer kan op beide manieren worden geïnterpreteerd.

Runtime-serialisatie (waarvan de BinaryFormatterdeel uitmaakt) serialiseert de feitelijke .NET-typen naar de andere kant, dus als u een List<int>verzendt, wordt de andere kant krijgt een List<int>.

Dat werkt natuurlijk beter als de andere kant .NET gebruikt.


Antwoord 4

De XmlSerializer serialiseert het type door alle eigenschappen van het type te lezen die zowel een openbare getter als een openbare setter hebben (en ook alle openbare velden). In die zin serialiseert/deserialiseert de XmlSerializer de “openbare weergave” van de instantie.

De binaire formatter, daarentegen, rangschikt een type door de “internals” van de instantie, d.w.z. de velden, te serialiseren. Alle velden die niet zijn gemarkeerd als [NonSerialized] worden geserialiseerd naar de binaire stream. Het type zelf moet worden gemarkeerd als [Serializable], evenals alle interne velden die ook moeten worden geserialiseerd.


Antwoord 5

Ik denk dat een van de belangrijkste is dat binaire serialisatie zowel openbare als privé-leden kan serialiseren, terwijl de andere alleen werkt met openbare.

Hierin biedt het een zeer nuttige vergelijking tussen deze twee in termen van grootte. Het is een zeer belangrijke kwestie, omdat u uw geserialiseerde object naar een externe machine zou kunnen sturen.

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

Other episodes