48 votes

Quelles sont les différences entre XmlSerializer et BinaryFormatter ?

La semaine dernière, j'ai passé une bonne partie du temps à travailler sur la sérialisation. Pendant cette période, j'ai trouvé de nombreux exemples utilisant soit le BinaryFormatter, soit le XmlSerializer. Malheureusement, je n'ai pas trouvé d'exemples détaillant de manière exhaustive les différences entre les deux.

La genèse de ma curiosité réside dans la raison pour laquelle le BinaryFormatter est capable de désérialiser directement vers une interface alors que le XmlSerializer ne l'est pas. Jon Skeet dans une réponse à " coulage vers plusieurs (types inconnus) au moment de l'exécution "fournit un exemple de sérialisation binaire directe vers une interface. Stan R. m'a fourni les moyens d'atteindre mon objectif en utilisant le XmlSerializer dans sa réponse à la question " Désérialisation des objets XML vers l'interface ."

Au-delà de l'évidence que le BinaryFormatter utilise la sérialisation binaire tandis que le 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.

93voto

Dustin Hodges Points 1959

La raison pour laquelle un formateur binaire est capable de désérialiser directement vers un type d'interface est que lorsqu'un objet est sérialisé à l'origine vers un flux binaire, des métadonnées contenant des informations de type et d'assemblage sont collées avec les données de l'objet. Cela signifie que lorsque le formateur binaire désérialise l'objet, il connaît son type, construit l'objet correct et peut ensuite le convertir en un type d'interface que l'objet implémente.

Le sérialiseur XML, quant à lui, se contente de sérialiser un schéma et ne sérialise que les champs et valeurs publics de l'objet, sans autre information sur le type (par exemple, les interfaces que le type implémente).

Voici un bon article, Sérialisation .NET en comparant les BinaryFormatter , SoapFormatter et XmlSerializer . Je vous recommande de consulter le tableau suivant qui, en plus des sérialiseurs mentionnés précédemment, comprend les éléments suivants DataContractSerializer , NetDataContractSerializer y protobuf-net .

Serialization Comparison

6voto

Marc Gravell Points 482669

Juste pour peser dans la balance...

La différence évidente entre les deux est "binaire vs xml", mais c'est beaucoup plus profond que cela :

  • champs ( BinaryFormatter =bf) vs public membres (généralement des propriétés) ( XmlSerializer =xs)
  • basé sur les métadonnées de type (bf) vs basé sur le contrat (xs)
  • version-brittle (bf) vs version-tolerant (xs)
  • "graphe" (bf) vs "arbre" (xs)
  • Spécifique à .NET (bf) vs portable (xs)
  • opaque (bf) vs lisible par l'homme (xs)

Comme une discussion sur les raisons pour lesquelles BinaryFormatter peuvent être fragiles, voir ici .

Il est impossible de déterminer lequel des deux est le plus important ; toutes les métadonnées de type dans le système de gestion de l'information de l'Union européenne (UE) ont été utilisées. BinaryFormatter peut le rendre plus grand. Et XmlSerializer peut très bien fonctionner avec une compression comme gzip.

Il est toutefois possible de tirer parti des points forts de chacun d'eux. Par exemple, Google a mis en libre accès son propre format de sérialisation des données, les "tampons de protocole". C'est le cas :

  • sur la base de contrats
  • portable (voir liste des mises en œuvre )
  • tolérant aux versions
  • basé sur les arbres
  • opaque (bien qu'il existe des outils permettant d'afficher les données lorsqu'elles sont combinées avec un .proto)
  • typiquement " contrat premier "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 comme l'encodage de la base 7 en longueur variable), et très efficaces à traiter (pas de structure xml complexe, pas de chaînes à faire correspondre aux membres, etc.)

Je suis peut-être un peu partial, car je maintiens l'une des implémentations (dont plusieurs sont adaptées à C#/.NET), mais vous remarquerez que je n'ai pas fait de lien vers le site Web de la société. lié à cualquier une mise en œuvre spécifique ; le format se suffit à lui-même ;-p

2voto

John Saunders Points 118808

Le sérialiseur XML produit du XML et aussi un schéma XML (implicitement). Il produira un XML conforme à ce schéma.

L'une des conséquences est qu'il ne sérialise rien qui ne puisse être décrit dans le schéma XML. Par exemple, il n'existe aucun moyen de faire la distinction entre une liste et un tableau dans le schéma XML, de sorte que le schéma XML produit par le sérialiseur peut être interprété dans les deux sens.

La sérialisation au moment de l'exécution (que l BinaryFormatter fait partie) sérialise les types .NET réels de l'autre côté, donc si vous envoyez un message de type List<int> l'autre partie obtiendra un List<int> .

Cela fonctionne évidemment mieux si l'autre partie utilise .NET.

1voto

Rob Levine Points 20793

Le 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, le 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 "internes" de l'instance, c'est-à-dire ses champs. Tous les champs qui ne sont pas marqués comme [NonSerialized] seront sérialisés dans le flux binaire. Le type lui-même doit être marqué comme [Serializable], tout comme les champs internes qui doivent également être sérialisés.

0voto

paradisonoir Points 991

Je pense que l'une des plus importantes est que la sérialisation binaire peut sérialiser les membres publics et privés, alors que l'autre ne fonctionne qu'avec les membres publics.

Il fournit ici une comparaison très utile entre les deux en termes de taille. C'est une question très importante, 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/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X