web-dev-qa-db-ja.com

XmlSerializerとBinaryFormatterの違いは何ですか

先週はかなりの時間をシリアル化に費やしました。その間、BinaryFormatterまたはXmlSerializerを利用する多くの例を見つけました。残念ながら、私が見つけられなかったのは、この2つの違いを包括的に詳しく説明する例はありませんでした。

私の好奇心の起源は、XmlSerializerがそうではないのにBinaryFormatterがインターフェイスに直接逆シリアル化できる理由にあります。 Jon Skeet実行時に複数の(不明なタイプ)へのキャスト 」への回答で、インターフェースへの直接バイナリシリアル化の例を示します。 Stan R。 は、「 XML Object Deserialization to Interface 」に対する彼の回答で、XmlSerializerを使用して私の目標を達成する手段を提供してくれました。

BinaryFormatterの明白な範囲を超えて、XmlSerializerがXMLを使用する一方で、バイナリシリアル化を利用して、根本的な違いをより完全に理解したいと思います。どちらを使用するかと、それぞれの長所と短所。

48
ahsteele

バイナリフォーマッタがインターフェイス型に直接逆シリアル化できる理由は、オブジェクトが元々、型を含むバイナリストリームメタデータにシリアル化され、アセンブリ情報がオブジェクトデータに組み込まれているためです。これは、バイナリフォーマッタがその型を知っているオブジェクトを逆シリアル化するときに、正しいオブジェクトを構築し、そのオブジェクトを実装するインターフェイス型にキャストできることを意味します。

一方、XMLシリアライザはスキーマにシリアル化するだけで、オブジェクトのパブリックフィールドと値のみをシリアル化し、それ以外の型情報はシリアル化しません(たとえば、型が実装するインターフェイス)。

。NETシリアライゼーション は、 BinaryFormatterSoapFormatter 、および XmlSerializer を比較したものです。前述のシリアライザーに加えて、 DataContractSerializerNetDataContractSerializer および protobuf-net を含む次の表を参照することをお勧めします。

Serialization Comparison

93
Dustin Hodges

計量するだけです...

この2つの違いは「バイナリとxml」の違いですが、それよりもさらに深くなっています。

  • フィールド(BinaryFormatter = bf)対publicメンバー(通常はプロパティ)(XmlSerializer = xs)
  • タイプメタデータベース(bf)とコントラクトベース(xs)
  • バージョン脆性(bf)とバージョントレラント(xs)
  • 「グラフ」(bf)対「ツリー」(xs)
  • .NET固有(bf)とポータブル(xs)
  • 不透明(bf)と人間が読める形式(xs)

BinaryFormatterが脆弱になる理由の説明として、 ここを参照 を使用します。

どちらが大きいかを議論することは不可能です。 BinaryFormatterのすべての型メタデータは、それを大きくすることができます。そしてXmlSerializerはgzipのような圧縮で非常に機能します。

ただし、それぞれの長所を利用することは可能です。たとえば、Googleは独自のデータシリアル化フォーマットである「プロトコルバッファ」をオープンソース化しています。これは:

  • 契約ベース
  • 移植可能( 実装リスト を参照)
  • バージョントレラント
  • ツリーベース
  • 不透明(.protoと組み合わせるとデータを表示するツールがあります)
  • 通常は " contract first "ですが、一部の実装では、リフレクションに基づいた暗黙のコントラクトが許可されています

しかし、重要なことに、それは非常に密度の高いデータ(タイプメタデータ、純粋なバイナリ表現、短いタグ、バリアントレングスのbase-7エンコーディングなどのトリック)であり、処理が非常に効率的です(複雑なxml構造、メンバーに一致する文字列がないなど) )。

私は少し偏っているかもしれません。私は実装の1つ(C#/。NETに適したいくつかを含む)を維持していますが、any特定の実装にはリンクしていません。このフォーマットは独自のメリットに基づいています;-p

6
Marc Gravell

XMLシリアライザは、XMLとXMLスキーマも(暗黙的に)生成します。このスキーマに準拠するXMLを生成します。

1つの意味は、XMLスキーマで記述できないものはシリアル化されないことです。たとえば、XMLスキーマではリストと配列を区別する方法がないため、シリアライザによって生成されたXMLスキーマはどちらの方法でも解釈できます。

ランタイムシリアル化(BinaryFormatterはその一部)は、実際の.NETタイプを反対側にシリアル化します。したがって、List<int>、反対側はList<int>

反対側が.NETを実行している場合は、明らかにうまくいきます。

2
John Saunders

XmlSerializerは、パブリックゲッターとパブリックセッター(およびパブリックフィールド)の両方を持つすべての型のプロパティを読み取ることで、型をシリアル化します。この意味で、XmlSerializerはインスタンスの「パブリックビュー」をシリアライズ/デシリアライズします。

対照的に、バイナリフォーマッタは、インスタンスの「内部」、つまりそのフィールドをシリアル化することにより、型をシリアル化します。 [NonSerialized]としてマークされていないフィールドは、バイナリストリームにシリアル化されます。タイプ自体も[Serializable]としてマークする必要があります。これは、シリアル化されるすべての内部フィールドも同様です。

1
Rob Levine

最も重要なものの1つは、バイナリシリアル化ではパブリックメンバーとプライベートメンバーの両方をシリアル化できるのに対し、もう1つはパブリックメンバーでしか機能しないことです。

ここでは、サイズの点でこれら2つの間の非常に役立つ比較を提供します。シリアル化されたオブジェクトをリモートマシンに送信する可能性があるため、これは非常に重要な問題です。

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

0
paradisonoir