51

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

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

XmlSerializer が XML を使用しているのに対し、BinaryFormatter はバイナリ シリアル化を利用していることは明らかですが、基本的な違いをより完全に理解したいと思います。どちらをいつ使用するか、およびそれぞれの長所と短所。

4

5 に答える 5

101

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

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

これは、 BinaryFormatterSoapFormatter、およびXmlSerializerを比較した良い投稿.NETSerializationです。次の表を参照することをお勧めします。これらの表には、前述のシリアライザーに加えて、DataContractSerializerNetDataContractSerializer、およびprotobuf-netが含まれています。

シリアル化の比較

于 2009-07-20T16:04:45.820 に答える
6

計量するだけです...

2つの明らかな違いは「binaryvsxml」ですが、それよりもはるかに深くなります。

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

BinaryFormatterなぜもろくなる可能性があるのか​​についての議論として、ここを参照してください

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

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

  • 契約ベース
  • ポータブル(実装のリストを参照)
  • バージョントレラント
  • ツリーベース
  • 不透明(.protoと組み合わせたときにデータを表示するツールがありますが)
  • 通常は「最初に契約」しますが、一部の実装では、リフレクションに基づく暗黙的な契約が許可されます

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

私は少し偏っているかもしれません。私は実装の1つ(C#/。NETに適したいくつかを含む)を維持していますが、特定の実装にリンクしていないことに気付くでしょ。フォーマットはそれ自身のメリットの下にあります;-p

于 2009-08-16T21:02:12.890 に答える
2

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

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

ランタイム シリアライゼーション ( のBinaryFormatter一部) は、実際の .NET 型を反対側にシリアライズするため、 を送信するList<int>と、反対側はList<int>.

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

于 2009-07-20T15:35:50.840 に答える
1

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

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

于 2009-07-20T15:26:59.750 に答える
0

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

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

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

于 2009-07-20T15:42:33.290 に答える