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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    Давайте будем гением компьютера.