Подтвердить что ты не робот

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

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

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

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

4b9b3361

Ответ 1

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

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

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

Serialization Comparison

Ответ 2

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

Очевидное различие между ними - "двоичный vs xml", но он намного глубже:

  • (BinaryFormatter= bf) vs public члены (обычно свойства) (XmlSerializer= xs)
  • Тип-метаданные (bf) и контрактные (xs)
  • версия-хрупкая (bf) и версия-толерантная (xs)
  • "graph" (bf) vs "tree" (xs)
  • .NET specific (bf) vs portable (xs)
  • непрозрачный (bf) и понятный для человека (xs)

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

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

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

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

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

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

Ответ 3

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

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

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

Это очевидно работает лучше, если другая сторона работает .NET.

Ответ 4

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

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

Ответ 5

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

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

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