web-dev-qa-db-fra.com

Quelles sont les différences entre XmlSerializer et BinaryFormatter

La semaine dernière, j'ai passé pas mal de temps à travailler sur la sérialisation. Au cours de cette période, j'ai trouvé de nombreux exemples utilisant soit BinaryFormatter, soit XmlSerializer. Malheureusement, ce que je n'ai pas trouvé, ce sont des exemples détaillant en détail les différences entre les deux.

La genèse de ma curiosité réside dans la raison pour laquelle BinaryFormatter est capable de se désérialiser directement sur une interface alors que XmlSerializer ne l’est pas. Jon Skeet dans une réponse à " transtypage en multiples (types inconnus) à l'exécution " fournit un exemple de sérialisation binaire directe sur une interface. Stan R. m'a fourni les moyens d'accomplir mon objectif en utilisant XmlSerializer dans sa réponse à " La désérialisation d'objet XML en interface ."

Au-delà de l'évidence de BinaryFormatter utilise la sérialisation binaire tandis que XmlSerializer utilise XML. J'aimerais mieux comprendre les différences fondamentales. Quand utiliser l'un ou l'autre et les avantages et inconvénients de chacun.

48
ahsteele

La raison pour laquelle un formateur binaire peut désérialiser directement sur un type d'interface est due au fait qu'un objet est sérialisé à l'origine sur un métadonnées de flux binaire contenant le type et que les informations d'assemblage sont bloquées dans les données de l'objet. Cela signifie que lorsque le formateur binaire désérialise l'objet, il connaît son type, génère l'objet correct et vous pouvez ensuite le transtyper en un type d'interface que l'objet implémente. 

Le sérialiseur XML, d'autre part, ne fait que sérialiser un schéma et ne sérialise que les champs et les valeurs publics de l'objet et aucune information de type autre que celle (par exemple, les interfaces implémentées par le type).

Voici un bon article, Serialization .NET , comparant les BinaryFormatter , SoapFormatter et XmlSerializer . Je vous recommande de consulter le tableau ci-dessous qui, en plus des sérialiseurs susmentionnés, inclut le DataContractSerializer , NetDataContractSerializer et protobuf-net .

Serialization Comparison

91
Dustin Hodges

Juste pour peser dedans ...

La différence évidente entre les deux est "binary vs xml", mais elle va beaucoup plus loin que cela:

  • champs (BinaryFormatter = bf) vs membres public (généralement des propriétés) (XmlSerializer = xs)
  • métadonnées de type (bf) vs contractuelles (xs)
  • version-friable (bf) vs version-tolérante (xs)
  • "graph" (bf) vs "arbre" (xs)
  • Spécifique .NET (bf) vs portable (xs)
  • opaque (bf) vs lisible par l'homme (xs)

Pour expliquer pourquoi BinaryFormatter peut être fragile, voir ici .

Il est impossible de discuter de ce qui est le plus gros. toutes les métadonnées de type dans BinaryFormatter peuvent l'agrandir. Et XmlSerializer peut très bien fonctionner avec la compression comme gzip.

Cependant, il est possible de prendre les forces de chacun; Par exemple, Google a ouvert son propre format de sérialisation de données, "tampons de protocole", en source ouverte. C'est:

  • basé sur le contrat
  • portable (voir liste des implémentations )
  • version tolérante
  • à base d'arbre
  • opaque (bien qu'il existe des outils pour afficher les données lorsqu'elles sont combinées avec un .proto)
  • typiquement " contract first ", mais certaines implémentations permettent des contrats implicites basés sur la réflexion

Mais surtout, il s’agit de données très denses (pas de métadonnées de type, représentation binaire pure, balises courtes, astuces telles que l’encodage base-7 à longueur variable), et très efficaces pour le traitement (pas de structure xml complexe, pas de chaîne à faire correspondre aux membres, etc. ).

Je pourrais être un peu partial Je maintiens une des implémentations (y compris plusieurs convenant à C #/.NET), mais vous remarquerez que je ne l’ai pas fait lié à toute mise en œuvre spécifique; le format repose sur ses propres mérites ;-p

6
Marc Gravell

Le sérialiseur XML produit du XML ainsi qu'un schéma XML (implicitement). Il produira du XML conforme à ce schéma.

Une implication est que cela ne sérialisera rien qui ne puisse être décrit dans XML Schema. Par exemple, il n'existe aucun moyen de faire la distinction entre une liste et un tableau dans XML Schema. Par conséquent, le schéma XML produit par le sérialiseur peut être interprété dans les deux sens.

La sérialisation à l'exécution (dont le BinaryFormatter fait partie) sérialise les types .NET réels de l'autre côté. Ainsi, si vous envoyez un List<int>, l'autre côté obtiendra un List<int>.

Cela fonctionne évidemment mieux si l'autre côté exécute .NET.

2
John Saunders

XmlSerializer sérialise le type en lisant toutes les propriétés du type qui ont à la fois un getter public et un setter public (ainsi que tous les champs publics). En ce sens, XmlSerializer sérialise/désérialise la "vue publique" de l'instance.

Le formateur binaire, en revanche, sérialise un type en sérialisant les "éléments internes" de l'instance, c'est-à-dire ses champs. Tous les champs qui ne sont pas marqués comme [Non sérialisés] seront sérialisés dans le flux binaire. Le type lui-même doit être marqué comme [Serializable], de même que tous les champs internes à sérialiser.

1
Rob Levine

Je suppose que l’un des plus importants est que la sérialisation binaire peut sérialiser les membres publics et privés, alors que l’autre ne fonctionne qu'avec des membres publics. 

Ici, il fournit une comparaison très utile entre ces deux en termes de taille. C'est un problème très important, car vous pourriez envoyer votre objet sérialisé à une machine distante.

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

0
paradisonoir