Каковы различия между XmlSerializer и BinaryFormatter - PullRequest
48 голосов
/ 20 июля 2009

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

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

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

Ответы [ 5 ]

92 голосов
/ 20 июля 2009

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

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

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

Serialization Comparison

6 голосов
/ 17 августа 2009

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

Очевидное различие между ними - «двоичный файл против xml», но оно намного глубже:

  • поля (BinaryFormatter = bf) против public члены (обычно свойства) (XmlSerializer = xs)
  • на основе типа метаданных (bf) по сравнению с контрактом (xs)
  • версия-хрупкая (bf) против версии-устойчивой (xs)
  • "график" (bf) против "дерева" (xs)
  • .NET специфично (bf) и переносимо (xs)
  • непрозрачный (bf) и читаемый человеком (xs)

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

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

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

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

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

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

2 голосов
/ 20 июля 2009

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

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

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

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

1 голос
/ 20 июля 2009

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

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

0 голосов
/ 20 июля 2009

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...