¿Cuáles son las diferencias entre XmlSerializer y BinaryFormatter?

Pasé una buena parte de tiempo la semana pasada trabajando en la serialización. Durante ese tiempo encontré muchos ejemplos utilizando BinaryFormatter o XmlSerializer. Desafortunadamente, lo que no encontré fueron ejemplos que detallen las diferencias entre los dos.

La génesis de mi curiosidad radica en por qué BinaryFormatter puede deserializarse directamente en una interfaz mientras que XmlSerializer no. Jon Skeet en una respuesta a ” conversión a múltiples (tipos desconocidos) en tiempo de ejecución ” proporciona un ejemplo de serialización binaria directa a una interfaz. Stan R. me proporcionó los medios para lograr mi objective utilizando XmlSerializer en su respuesta a ” Deserialización de objetos XML a la interfaz “.

Más allá de lo obvio de que BinaryFormatter utiliza la serialización binaria, mientras que XmlSerializer usa XML me gustaría entender más completamente las diferencias fundamentales. Cuándo usar uno u otro y los pros y los contras de cada uno.

La razón por la que un formateador binario es capaz de deserializar directamente a un tipo de interfaz es porque cuando un objeto se serializa originalmente en una secuencia binaria, los metadatos que contienen el tipo y la información de ensamblaje quedan atrapados con los datos del objeto. Esto significa que cuando el formateador binario deserializa el objeto, conoce su tipo, crea el objeto correcto y luego puede convertirlo en un tipo de interfaz que ese objeto implemente.

El serializador XML, por otro lado, solo se serializa en un esquema y solo serializa los campos públicos y los valores del objeto y no hay otro tipo de información (por ejemplo, las interfaces que implementa el tipo).

Aquí hay una buena publicación, Serialización .NET , que compara BinaryFormatter , SoapFormatter y XmlSerializer . Le recomiendo que consulte la siguiente tabla que, además de los serializadores mencionados anteriormente, incluye DataContractSerializer , NetDataContractSerializer y protobuf-net .

Comparación de serialización

Solo para pesar en …

La diferencia obvia entre los dos es “binario vs xml”, pero va mucho más allá que eso:

  • fields ( BinaryFormatter = bf) vs public members (típicamente propiedades) ( XmlSerializer = xs)
  • tipo-metadata basado (bf) vs contrato-basado (xs)
  • versión-frágil (bf) vs versión tolerante (xs)
  • “gráfico” (bf) vs “árbol” (xs)
  • .NET específico (bf) vs portable (xs)
  • opaco (bf) vs humano legible (xs)

Como una discusión de por qué BinaryFormatter puede ser frágil, mira aquí .

Es imposible discutir cuál es más grande; todos los metadatos de tipo en BinaryFormatter pueden hacerlo más grande. Y XmlSerializer puede funcionar muy bien con compresión como gzip.

Sin embargo, es posible tomar las fortalezas de cada uno; por ejemplo, Google ha abierto su propio formato de serialización de datos, “búferes de protocolo”. Esto es:

  • basado en contrato
  • portátil (ver lista de implementaciones )
  • tolerante a la versión
  • basado en árbol
  • opaco (aunque hay herramientas para mostrar datos cuando se combina con un .proto)
  • típicamente ” contrato primero “, pero algunas implementaciones permiten contratos implícitos basados ​​en la reflexión

Pero, lo que es más importante, es información muy densa (sin metadatos de tipo, representación binaria pura, tags cortas, trucos como encoding variant-length base-7) y muy eficiente de procesar (sin estructura XML compleja, sin cadenas para que coincida con los miembros, etc. )

Podría ser un poco parcial; Mantengo una de las implementaciones (incluidas varias adecuadas para C # / .NET), pero notará que no me he vinculado a ninguna implementación específica; el formato tiene sus propios méritos ;-p

XML Serializer produce XML y también un Esquema XML (implícitamente). Producirá XML que se ajuste a este esquema.

Una implicación es que no serializará nada que no pueda describirse en XML Schema. Por ejemplo, no hay manera de distinguir entre una lista y una matriz en el Esquema XML, por lo que el Esquema XML producido por el serializador se puede interpretar de cualquier manera.

La serialización en tiempo de ejecución (de la cual forma parte BinaryFormatter ) serializa los tipos de .NET reales al otro lado, por lo que si envía una List , la otra parte obtendrá una List .

Obviamente, esto funciona mejor si el otro lado ejecuta .NET.

El XmlSerializer serializa el tipo leyendo todas las propiedades del tipo que tienen tanto un public getter como un public setter (y también cualquier campo público). En este sentido, el XmlSerializer serializa / deserializa la “vista pública” de la instancia.

El formateador binario, por el contrario, serializa un tipo serializando las “partes internas” de la instancia, es decir, sus campos. Cualquier campo que no esté marcado como [No serializado] se serializará en la secuencia binaria. El tipo en sí mismo debe marcarse como [Serializable] como cualquier otro campo interno que también se serializará.

Supongo que uno de los más importantes es que la serialización binaria puede serializar tanto miembros públicos como privados, mientras que la otra funciona solo con los públicos.

Aquí, proporciona una comparación muy útil entre estos dos en términos de tamaño. Es un tema muy importante, ya que puede enviar su objeto serializado a una máquina remota.

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