Десериализация типа в текущей позиции потока с помощью protobuf-net - PullRequest
7 голосов
/ 14 марта 2010

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

ProtoBuf.Serializer.Serialize(stream, postA1);
ProtoBuf.Serializer.Serialize(stream, postB1);
stream.Position = 0;
var postA2 = ProtoBuf.Serializer.Deserialize<Post>(stream);
var postB2 = ProtoBuf.Serializer.Deserialize<Post>(stream);

Первая десериализация перемещает поток в конец, и postA2 содержит значение postB1, тогда как postB2 является просто неинициализированным экземпляром. Это ожидаемое поведение, и если да, то как десериализовать объект из случайного положения в потоке?

1 Ответ

8 голосов
/ 14 марта 2010

По по умолчанию protobuf (спецификация Google, а не proobuf-net специально) предназначен для того, чтобы вы могли обрабатывать последовательные сообщения как часть одного объекта - то есть вы можете добавлять поля в сообщение просто конкатенация, которая, по сути, то, что вы делаете здесь. Каждый объект верхнего уровня (по умолчанию) не имеет какого-либо вида отделения от следующего объекта.

Чтобы заставить его обращаться с ними как с различными объектами, посмотрите на методы *WithLengthPrefix (или вы можете использовать версии IEnumerable<T> - возможно, DeserializeItems; обратите внимание также, что он будет автоматически применять префиксы длины, если вы дадите ему что-то). как список для сериализации); например:

По существу:

Serializer.SerializeWithLengthPrefix(stream, postA1, PrefixStyle.Base128, 1);
Serializer.SerializeWithLengthPrefix(stream, postB1, PrefixStyle.Base128, 1);
stream.Position = 0;
var postA2 = Serializer.DeserializeWithLengthPrefix<Post>(stream,
    PrefixStyle.Base128, 1);
var postB2 = Serializer.DeserializeWithLengthPrefix<Post>(stream,
    PrefixStyle.Base128, 1);
...