Массив байтов сериализации и XML-файл - PullRequest
4 голосов
/ 20 февраля 2009

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

  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

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

Ответы [ 7 ]

6 голосов
/ 20 февраля 2009

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

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

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

objectToDeserialize = bf.Deserialize(inputStream) as DeserializedType;

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

2 голосов
/ 21 февраля 2009

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

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

1 голос
/ 20 февраля 2009

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

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

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

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

0 голосов
/ 20 февраля 2009
Библиотека

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

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


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

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

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

0 голосов
/ 20 февраля 2009

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

Хорошее обсуждение сериализации Java смотрите на Эффективная Java (в частности, глава 10).

Для C # не уверен, но, вероятно, основные проблемы те же.

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

0 голосов
/ 20 февраля 2009

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

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

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

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

0 голосов
/ 20 февраля 2009

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

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

...