В чем разница между XmlSerializer и BinaryFormatter

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

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

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


person ahsteele    schedule 20.07.2009    source источник


Ответы (5)


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

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

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

Сравнение сериализации

person Dustin Hodges    schedule 20.07.2009
comment
Хороший стол. Меня всегда раздражало отсутствие универсальных шаблонов SOAP. - person Callum Rogers; 20.07.2009
comment
Я считаю, что классификация лучших показателей неверна. Программа форматирования двоичных файлов является наихудшим сериализатором в .NET (за исключением, может быть, программы форматирования мыла). По крайней мере, это то, что показывают большинство тестов: blogs.msdn.com/b/youssefm/archive/2009/07/10/, james.newtonking.com/archive/2010/01/01/, techmikael.blogspot.com/2010/01/ - person joniba; 13.07.2011
comment
@joniba Я не щелкнул, чтобы прочитать упомянутые статьи, но если это не двоичный форматтер, какой сериализатор имеет лучшую производительность? - person ahsteele; 14.08.2011
comment
@ahsteele В этом конкретном списке сначала будет Protobuf-net, а затем DataContractSerializer - person joniba; 17.08.2011
comment
@CallumRogers форматировщик мыла устарел с .net 2.0 в пользу XmlSerializer, поэтому никогда не обновлялся для дженериков. - person MikeT; 01.03.2017
comment
@joniba лучшая производительность всегда зависит от использования, XML не использует повторно элементы, поэтому любой набор данных, содержащий много общих ссылок, будет иметь много дублирования в процессе XML, что снизит производительность, но тесты с плоскими объектами будут отдавать предпочтение XML - person MikeT; 01.03.2017

Просто чтобы взвесить ...

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

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

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

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

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

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

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

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

person Marc Gravell    schedule 16.08.2009

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

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

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

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

person John Saunders    schedule 20.07.2009
comment
привет, Джон, мне просто интересно, не проблема ли обработка списка ‹T›, вы все равно предпочли бы BinaryFormatter? - person paradisonoir; 20.07.2009
comment
Нет. Список был просто примером. У этих двух совершенно разные варианты использования. Кстати, см. SoapFormatter. Сериализация среды выполнения (два средства форматирования) полностью отличается от сериализации XML, которая сильно отличается от сериализации контракта данных. - person John Saunders; 20.07.2009

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

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

person Rob Levine    schedule 20.07.2009

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

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

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

person paradisonoir    schedule 20.07.2009
comment
ссылка мертва и не заархивирована. - person Martin Schneider; 25.05.2018