2009-02-20 3 views
4

Я использую массив байтов для передачи объектов, примитивных данных по сети и обратно. Я адаптирую подход java, имея реализацию типа ISerializable, которая содержит два метода, как часть интерфейса, ReadObjectData и WriteObjectData. Любой класс, использующий этот интерфейс, записывает дату в массив байтов. Что-то вроде этогоСериализация байтового массива против файла XML

class SerializationType:ISerializable 
    { 
     void ReadObjectData (/*Type that manages the write/reads into the byte array*/){} 
     void WriteObjectData(/*Type that manages the write/reads into the byte array*/){} 
    } 

После того, как запись завершена для всего объекта, я посылаю массив сети.


Это фактически двузначный вопрос. Правильный ли способ передачи данных по сети для максимальной эффективности (с точки зрения скорости, размера)?

Используете ли вы этот подход для записи объектов в файл, в отличие от типичной сериализации XML?

Редактировать # 1

Joel Coehoorn упоминается BinaryFormatter. Я никогда не использовал этот класс. Не могли бы вы разработать, предоставить хороший пример, ссылки, рекомендации, текущую практику - в дополнение к тому, что я сейчас вижу в msdn?

ответ

6

Это должно быть хорошо, но вы выполняете работу, которая уже сделана для вас. Посмотрите на класс System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.

Вместо того чтобы использовать собственные методы Read/WriteOjbectData() для каждого конкретного типа, вы можете просто использовать этот класс, который уже может обрабатывать большинство объектов. Это в основном принимает точную копию представления памяти практически любого объекта .Net и записывает его или читает его из потока:

BinaryFormatter bf = new BinaryFormatter(); 
bf.Serialize(outputStream, objectToSerialize); 

objectToDeserialize = bf.Deserialize(inputStream) as DeserializedType; 

Убедитесь, что вы прочитали связанные документы: там могут быть проблемы с юникод строками , и точное представление памяти не всегда подходит (например, открытые сокеты).

+0

Ницца ... продумайте этот класс, пожалуйста .... – 2009-02-20 17:55:37

+0

Это может не сработать, если требуется конкретный макет в двоичном массиве. – 2009-02-20 18:33:01

+0

Правильно: он принимает на себя .Net на обоих концах, или что любой участник, не являющийся участником, будет анализировать формат .Net. –

0

Создание собственного интерфейса ISerializable, когда есть уже один в структуре, похоже на немного рецепт катастрофы. По крайней мере, дать ему другое имя.

У вас будет небольшая проблема, когда дело доходит до чтения - у вас не будет экземпляра для вызова метода. Вы можете захотеть сделать это своим родом «фабрика» вместо:

public interface ISerializationFactory<T> 
{ 
    T ReadObjectData(Stream input); 
    void WriteObjectData(Stream output); 
} 

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

+0

Когда был введен ISerializationFactory?ISerializable является внутренним интерфейсом, поэтому я могу легко модифицировать все типы сериализации. Я запомню это. Спасибо – 2009-02-20 17:43:47

0

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

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

+0

Хорошая идея. Я полагаю, что для хранения файла XML-файл - хорошая идея. Что касается банковского перевода, специфичного для моего случая, я не могу использовать xml, так как другой конечный получающий данные - это сервер C++, который только считывает и записывает данные в одну сторону, а один путь - в/из байтового массива. Спасибо – 2009-02-20 17:42:05

0

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

Если вы хотите, чтобы это было понятным для человека, то XML - это что-то, что нужно учитывать, но оно зависит от типа данных, который вам нужно для сериализации. XML по своей сути рекурсивный и поэтому хорош для сериализации аналогично рекурсивных данных. Это меньше подходит для других типов данных.

Другими словами, выберите устойчивую сериализацию, соответствующую вашим потребностям. Здесь нет одностороннего решения.

Что касается сети, как правило, вы хотите, чтобы размер был минимальным, поэтому XML обычно не является хорошим выбором из-за его многословия.

0

Сериализация (на языке Java) обманчиво проста. До тех пор, пока вы делаете простые вещи (например, никогда не меняете класс), это легко, но с ним также есть множество «забавных» вещей.

Протезируйте хорошее обсуждение сериализации Java на Effective Java (в частности, глава 10).

Для C#, не уверен, но, вероятно, основные проблемы одинаковы.

Здесь приведен пример на сериализации C#: http://www.codeproject.com/KB/cs/objserial.aspx.

+0

Эффективная Java - отличная книга - я прочитал обложку обоих изданий для обложки! – 2009-02-20 17:52:22

0

XStream библиотека обеспечивает исключительно хороший способ работы с сериализацией, включая поддержку XML, JSON и поддержку пользовательских преобразователей. В частности, использование пользовательских преобразователей позволило нам уменьшить объемность XML и строго сериализовать то, что необходимо.

У XStream нет требования объявлять все как Serializable, что очень важно при использовании сторонней библиотеки и необходимо сериализовать экземпляр класса из этой библиотеки, который не объявляется как Serializable.


Ответ уже принят, но для полноты этой дискуссии здесь есть ссылка на хорошее сравнение между различными сериализации подходов/библиотек:

http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

В kryo библиотека выглядит очень убедительно для сериализации Java. Подобно XStream поддерживает пользовательские преобразователи.

+0

выглядит хорошо [для личного пользования]. Я не уверен, что хочу включить его в коммерческий код, пока, по крайней мере, я полностью не пойму правила лицензии. Это облегчает сериализацию файлов. Мне тоже нужно что-то для сети. спасибо – 2009-02-20 20:55:20

+0

Мы используем его специально для сетевой связи (как способ связи между службой REST и клиентом). В двухминутном учебнике [http://xstream.codehaus.org/tutorial.html] показано, что можно просто написать String xml = xstream.toXML (joe); а затем делать с xml то, что когда-либо необходимо. – 01es

2

Если вы используете простую, легкую и эффективную двоичную сериализацию, рассмотрите protobuf-net; основанный на формате буферов протокола Google, но реализованный с нуля для типичного использования .NET. В частности, он может использоваться как автономно (через protobuf-net Serializer), либо через BinaryFormatter путем реализации ISerializable (и делегирования на Serializer).

Помимо этого, этот формат предназначен для расширения и переносимости (то есть совместимого с реализацией протокольных буферов java/php/C++), в отличие от BinaryFormatter, который является как специфичным для реализации, так и версией-нетерпимым. И это означает, что вам не нужно возиться с написанием кода сериализации ...

Смежные вопросы