2011-02-26 1 views
2

は、私は基本的に自分自身のバイナリシリアライゼーションクラス、ちょっとBinaryFormatterクラスが何をしているのかを作成したいです。これを行うには、どうすればBinaryReaderBinaryWriterクラスを使用できますか? 私はアイデアのコードを望んでいません。おかげさまで PS:BinaryFormatterを使用するように教えてください。BinaryReaderとBinaryWriterを使用して独自のバイナリシリアライザを作成するにはどうすればよいですか?

+0

BinaryFormatterに何が問題なのか正確に答えることは不可能です。あなたのバージョンはどのように*正確に*動作する必要がありますか? –

+0

私はこれを学習の練習としてやっています。 BinaryFormatterに全く問題はありません+ CFでBinaryFormatterがサポートされていないため、両方の方法で軽量フォーマッタを使用したいと思います。 – gigi

+0

は、ああ、私は始めていない@Hans :)私は...その***全ての午後***についてあなたはまた、既存の公共バイナリシリアル形式で見たいと思うかもしれません –

答えて

0

シリアル化の実装方法を確認するには、C#のソースコードsharpserializerを参照してください。ソースコードはhereです。コードはwindowsmobile、silverlightでも動作します。

3

最終的には、種類ごとの戦略を選択した後、ちょうどそれぞれに切り替える必要があり、 BinaryWriterにはInt32、Stringなどを書き込むメソッドがあるので、基本的なアプローチはte FieldInfo/PropertyInfoの有効なタイプのGetTypeCodeで多くのリフレクションとスイッチを使用することです。

私は実際にこれを行って、私は実際にを避ける BinaryReader/Writer、そしてストリームのためにまっすぐに行く(働くための浮動小数点[]バッファで)。

は、高度な取得、あなたはメンバーごと、またはタイプのプリコンパイル何かにメタプログラミングを使って反射量を減らすかもしれません。

他の事は考慮します(もしあれば)

  • がどのようにサブオブジェクト/継承/リストをパックしようとしている各データフィールドをマークする

    • どのヘッダデータが必要なん

    どちらも簡単に解決できます

  • +0

    なぜあなたは 'BinaryReader'と' BinaryWriter'を避けますか?私は(ほとんど)良い効果のためにそれらを使用しました。私は今や邪魔になることを認めますが、一般的には好きです。 'byte []'バッファを使う利点は何ですか? –

    +0

    @ジム - 私の場合、データ形式はBinaryReader/Writerが選択するもの(protobufはvarint可変長エンコーディングを使用します)と完全に一致せず、かなりのバイナリジャグリングがあります。それをスクラッチバッファに直接書き込んで、Read/Write呼び出しの回数を最小限に抑えることもできます。フルになったらバッファがフラッシュされることに注意してください。メモリ全体をアセンブルしないでください(メモリオーバーヘッドが大きくなります)。しかし、主に最初の理由:それは私にanythigを提供してくれませんでした –

    +0

    ええ、可変長エンコーディングは、それらの痛みのようなものです。情報をありがとう。 –

    0

    私は、セットアップクラスの属性を使用してすることができますし、それがすべてのバイナリシリアライズ/デシリアライズを処理するた、ProtoBuf .Netのようなものを使用することをお勧めします。

    私は最近、よりコンパクトな形式でジェネリッククラス内の顧客のシリアル化のサポートを提供することを強化しなければなりませんでした。 Marcと同様に、特定の型のシリアル化/逆シリアル化を処理し、次に書きたい特定のオブジェクトの型のコードを実行するように切り替えるコードを持つだけです。ここで

    は、私はジェネリッククラス内のデータの直列化を可能にするために取ったアプローチの基本的なアウトラインです:

    MemoryStream stream = new MemoryStream(); 
    BinaryWriter writer = new BinaryWriter(stream); 
    
    writer.Write(_size); 
    for (int i = 0; i < _size; i++) 
        _indices[i].AddToStream(writer); 
    
    if (_serializeDataToStream == null) 
        _serializeDataToStream = (Action<BinaryWriter, int, T[]>)GetTypeSpecificSerializationMethod(); 
    
    _serializeDataToStream(writer, _size, _data); 
    
    return stream.ToArray(); 
    

    それだけで見上げする必要があるので、これは一般的なクラスの内部で、_serializeDataToStreamは静的ですジェネリックタイプごとに1回

    private Delegate GetTypeSpecificSerializationMethod() 
    { 
        if (typeof(T) == typeof(double)) 
        { 
         MethodInfo method = this.GetType().GetMethod("SerializeDouble", BindingFlags.Static | BindingFlags.NonPublic); 
         return Delegate.CreateDelegate(typeof(Action<BinaryWriter, int, T[]>), method); 
        } 
        else if (typeof(T) == typeof(ushort)) 
        { 
        ... 
    
    
    private static void SerializeDouble(BinaryWriter writer, int size, double[] data) 
    { 
        for (int i = 0; i < size; i++) 
        { 
         writer.Write(data[i]); 
        } 
    } 
    
    関連する問題