Каковы различия между XmlSerializer и BinaryFormatter

Я провел большую часть времени на прошлой неделе, работая над сериализацией. За это время я нашел много примеров использования BinaryFormatter или XmlSerializer. К сожалению, я не нашел каких-либо примеров, всесторонне детализирующих различия между ними.

Генезис моего любопытства заключается в том, почему BinaryFormatter способен десериализоваться непосредственно на интерфейс, а XmlSerializer-нет. Джон Скит в ответ на "кастинг на несколько (неизвестных типов) во время выполнения " предоставляет пример прямой двоичной сериализации интерфейса. Стэн Р. предоставил мне средства для достижения моей цели, используя XmlSerializer в своем ответе на "десериализация объекта XML в интерфейс."

помимо очевидного BinaryFormatter использует двоичную сериализацию, в то время как XmlSerializer использует XML, я хотел бы более полно понять фундаментальные различия. Когда использовать тот или иной и плюсы и минусы каждого.

5 ответов


причина, по которой двоичный формататор может десериализоваться непосредственно в тип интерфейса, заключается в том, что когда объект первоначально сериализуется в метаданные двоичного потока, содержащие информацию о типе и сборке, застрял с данными объекта. Это означает, что при десериализации двоичного форматирующего объекта он знает его тип, строит правильный объект, и вы можете привести его к типу интерфейса, который реализует объект.

сериализатор XML на otherhand просто сериализуется в схему и сериализует только открытые поля и значения объекта и никакой другой информации о типе (например, интерфейсы, реализуемые типом).

вот хороший пост,сериализация .NET сравнение BinaryFormatter, SoapFormatter и XmlSerializer. Я рекомендую вам посмотреть следующую таблицу, которая в дополнение к ранее упомянутым сериализаторам включает DataContractSerializer, NetDataContractSerializer и protobuf-чистая.

Serialization Comparison


просто все взвесить...

очевидная разница между ними - "binary vs xml", но она намного глубже:

  • поля (BinaryFormatter =bf) vs общественные члены (обычно свойства) (XmlSerializer =xs)
  • Type-metadata based (bf) vs contract-based (xs)
  • версия-хрупкая (bf) против версии-толерантная (xs)
  • " graph "(bf) vs "tree" (xs)
  • специфический .NET (bf) против портативного (xs)
  • непрозрачный (bf) против читаемого человеком (xs)

как обсуждение почему BinaryFormatter может быть хрупким,посмотреть здесь.

невозможно обсудить, что больше; все метаданные типа в BinaryFormatter можете сделать его больше. И XmlSerializer может работать очень со сжатием, как gzip.

тем не менее, можно взять сильные стороны каждого; например, Google имеют открытый источник свой собственный формат сериализации данных, "буферы протокола". Это:

  • контракта
  • портативное (см. список внедрений)
  • версия-толерантного
  • древовидное
  • непрозрачный (хотя есть инструменты для отображения данных в сочетании со .proto)
  • как правило,"контракт Первого", но некоторые реализации позволяют неявные контракты, основанные на отражении

но главное, это очень плотные данные (нет типа метаданные, чистое двоичное представление, короткие теги, трюки, такие как кодировка Base-7 variant-length) и очень эффективны для обработки (без сложной структуры xml, без строк для соответствия членам и т. д.).

Я могу быть немного предвзятым; я поддерживаю одну из реализаций (включая несколько подходящих для C# / .NET), но вы заметите, что я не связан с любой конкретная реализация; формат стоит под своими достоинствами ; - p


сериализатор XML создает XML, а также XML-схему (неявно). Он будет производить XML, который соответствует этой схеме.

одним из следствий является то, что он не будет сериализовать ничего, что не может быть описано в схеме XML. Например, в XML-схеме невозможно провести различие между списком и массивом, поэтому XML-схему, созданную сериализатором, можно интерпретировать в любом случае.

сериализация времени выполнения (которая BinaryFormatter часть) сериализует фактический .NET типы на другую сторону, поэтому, если вы отправляете List<int>, другая сторона будет List<int>.

это, очевидно, работает лучше, если другая сторона работает .Сеть.


сериализатор XmlSerializer сериализует тип, считывая все свойства типа, которые имеют как общедоступный геттер, так и общедоступный сеттер (а также любые общедоступные поля). В этом смысле XmlSerializer сериализует/десериализует "общественное мнение" экземпляра.

двоичное форматирование, напротив, сериализует тип путем сериализации "внутренних" экземпляра, т. е. его полей. Все поля, которые не помечены как [Несериализованные], будут сериализованы в двоичный поток. Сам тип должен быть помечены как [сериализуемые], как и любые внутренние поля, которые также должны быть сериализованы.


Я думаю, один из самых важных заключается в том, что двоичная сериализация может сериализовать как публичные, так и частные члены, тогда как другой работает только с публичными.

здесь он обеспечивает очень полезное сравнение между этими двумя с точки зрения размера. Это очень важная проблема, потому что вы можете отправить сериализованный объект на удаленный машина.

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