Пример двоичного сериализатора клиента в .Net

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

Кроме того, мне лучше создать свой собственный класс сериализатора или просто реализовать ISerializable и использовать BinarySerializer? Если я реализую Iserializable, получится ли обойти проблемы с загрузкой сборки/зависимостью версии с помощью BinarySerializer?


person Kratz    schedule 14.04.2011    source источник
comment
В чем причина пользовательского двоичного сериализатора?   -  person Tomas McGuinness    schedule 14.04.2011
comment
+1 за Томаса. Я мог бы создать собственный XML-сериализатор, если вам нужно, чтобы XML выглядел очень специфическим образом, но для двоичного кода? Вы пытаетесь взаимодействовать с каким-то существующим API, где есть объекты, представленные в виде двоичных данных? Здесь нужно больше информации   -  person DarinH    schedule 14.04.2011
comment
Часть приложения работает как надстройка для AutoCAD. В этой ситуации десериализация всегда терпит неудачу, утверждая, что не может найти сборку. Я знаю, что сборка существует, потому что код из этой сборки должен быть запущен, прежде чем он дойдет до этой точки. Частично любознательность (мне нравится узнавать что-то новое).   -  person Kratz    schedule 14.04.2011
comment
@drventure, это еще и производительность. У меня уже есть собственный сериализатор XML, но его запуск может занять 20 секунд, пока пользователь его ждет.   -  person Kratz    schedule 14.04.2011
comment
в качестве примечания, вы можете исправить ошибки загрузки сборки, используя событие AssemblyLoad. Лично я согласен с @wal, но я немного предвзят   -  person Marc Gravell    schedule 14.04.2011


Ответы (2)


Ознакомьтесь с protobuf-net, написанным Марком Гравеллом (участником Stack Overflow)

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

Теперь я использую это после того, как мне надоело BinaryFormatter

Использовать protobuf легко и очень быстро, и он НЕ испытывает проблем с загрузкой сборки/зависимостью от версии.

Да, и если вам нужна статистика производительности, проверьте это. Быстро!

Я задал похожий вопрос об альтернативе BinaryFormatter

person wal    schedule 14.04.2011
comment
Сэкономил мне время на набор текста :) на самом деле, во многих отношениях код v1 и код v2 показывают 2 разных способа сделать это - переписывание внутри довольно жесткое. V1 доступен в виде пакета nuget внутри VS2010. - person Marc Gravell; 14.04.2011
comment
говоря о версии 2... как она выглядит? - person wal; 14.04.2011
comment
Сделал это, но вы должны отметить все поля для сериализации. У меня не просто много данных, а очень глубокая структура со многими классами. Похоже, что v2 решит эту проблему, но, похоже, она еще не вышла. - person Kratz; 14.04.2011
comment
Это ответ на мой вопрос, так как это пример двоичной сериализации. - person Kratz; 14.04.2011

Вот пример в vb.net

Я преобразовал его из некоторого С#, поэтому извините, если он не скомпилируется, но, надеюсь, поможет вам

Я также разместил код С#.

Если вам нужно сохранить сериализованный объект, я рекомендую использовать base64 для типа ntext, если вы используете ms sql.....

Мой пример сериализует весь объект this или me в vb.net, однако иногда вы можете захотеть получить полный контроль или у вас могут возникнуть проблемы с атрибутом безопасности, которые могут вызвать проблемы с безопасностью - если это так, вы можете сериализовать отдельные поля и удалить сериализацию атрибут. поэтому я включил код для сериализации отдельных полей - они закомментированы

Существует множество способов сериализации объектов в .NET, иногда атрибут Serialize может вызвать проблемы с безопасностью, тогда вам придется сериализовать каждое поле.

Imports System.Linq
Imports System.Collections.Generic
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.IO

Namespace ConsoleApp
    <Serializable> _
    Public Class Example
        Public Property S() As String
            Get
                Return m_S
            End Get
            Set
                m_S = Value
            End Set
        End Property
        Private m_S As String
        Public Property I() As Integer
            Get
                Return m_I
            End Get
            Set
                m_I = Value
            End Set
        End Property
        Private m_I As Integer
        Public Property List() As List(Of String)
            Get
                Return m_List
            End Get
            Set
                m_List = Value
            End Set
        End Property
        Private m_List As List(Of String)
        Public Function Pack() As Byte()
            Dim bf = New BinaryFormatter()
            Using ms = New MemoryStream()
                bf.Serialize(ms, Me)
                '               bf.Serialize(ms, S);
                '               bf.Serialize(ms, I);
                '               bf.Serialize(ms, List);
                Return ms.ToArray()
            End Using
        End Function
        Public Function UnPack(data As Byte()) As Example
            Dim bf = New BinaryFormatter()
            Using ms = New MemoryStream(data)
                    '               S = (string) bf.Deserialize(ms);
                    '               I = (int) bf.Deserialize(ms);
                    '               List = (List<string>) bf.Deserialize(ms);               
                Return DirectCast(bf.Deserialize(ms), Example)
            End Using
            '           return this;
        End Function
        Public Overrides Function ToString() As String
            Return String.Format("[Example: S={0}, I={1}, List={2}]", S, I, [String].Join(",", List.ToArray()))
        End Function
    End Class
    Class MainClass

        Public Shared Sub Main(args As String())

            Dim o1 = New Example() With { _
                Key .S = "James", _
                Key .I = 9, _
                Key .List = New List(Of String)(New String() {"a", "b"}) _
            }
            Dim o2 = New Example().UnPack(o1.Pack())
            Console.WriteLine(o1.ToString())
            Console.WriteLine(o2.ToString())

            Console.ReadLine()

        End Sub

    End Class
End Namespace

исходный код С#

using System;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace ConsoleApp
{
    [Serializable()]
    public class Example {
        public string S {get;set;}
        public int I {get;set;}
        public List<string> List {get; set;}
        public byte[] Pack() {
            var bf = new BinaryFormatter();
            using (var ms = new MemoryStream()) {
                bf.Serialize(ms, this);
//              bf.Serialize(ms, S);
//              bf.Serialize(ms, I);
//              bf.Serialize(ms, List);
                return ms.ToArray();
            }
        }
        public Example UnPack(byte[] data) {
            var bf = new BinaryFormatter();
            using (var ms = new MemoryStream(data)) {
                return (Example) bf.Deserialize(ms);
//              S = (string) bf.Deserialize(ms);
//              I = (int) bf.Deserialize(ms);
//              List = (List<string>) bf.Deserialize(ms);               
            }
//          return this;
        }
        public override string ToString ()
        {
            return string.Format ("[Example: S={0}, I={1}, List={2}]", S, I, String.Join(",", List.ToArray()));
        }
    }
    class MainClass
    {

        public static void Main (string[] args)
        {

            var o1 = new Example() {S = "James", I = 9, List= new List<string>(new string[] {"a", "b"})};
            var o2 = new Example().UnPack(o1.Pack());
            Console.WriteLine(o1.ToString());
            Console.WriteLine(o2.ToString());

            Console.ReadLine();

        }

    }
}
person James Kyburz    schedule 14.04.2011