views:

184

answers:

1

I'm serializing several objects into a single stream, but when i try to read them back, i can't seem to get anything but the last object:

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);

The first deserialize moves the stream to the end and postA2 contains the value of postB1, while postB2 is just an uninitialized instance. Is this expected behavior, and if so, how do you deserialize an object from a random position in a stream?

+2  A: 

By default, protobuf (the Google spec, not proobuf-net specifically) is designed to allow you to treat consecutive messages as part of a single object - i.e. you can add fields to a message simply by concatenating, which is essentially what you are doing here. Each top-level object does not (by default) have any kind of separation from the next object.

To get it to treat them as different objects, look at the *WithLengthPrefix methods (or you can use the IEnumerable<T> versions - perhaps DeserializeItems; note also that it will apply length prefixes automatically if you give it something like a list to serialize); for example:

Essentially:

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);
Marc Gravell
Exactly what i was looking for. I didn't get what DeserializeWithLengthPrefix did from looking at it. thx
Arne Claassen