6

I have a single file and need to serialize multiple objects of the same class when ever a new object is created. I can't store them in arrays as I need to serialize them the instance an object is create. Please, help me.

Preet Sangha
  • 64,563
  • 18
  • 145
  • 216

3 Answers3

7

What serialization mechanism are you using? XmlSerializer might be a problem because of the root node and things like namespace declarations, which are a bit tricky to get shot of - plus it isn't great at partial deserializations. BinaryFormatter is very brittle to begin with - I don't recommend it in most cases.

One option might be protobuf-net; this is a binary serializer (using Google's "protocol buffers" format - efficient, portable, and version-tolerant). You can serialize multiple objects to a stream with Serializer.SerializeWithLengthPrefix. To deserialize the same items, Serializer.DeserializeItems returns an IEnumerable<T> of the deserialized items - or you could easily make TryDeserializeWithLengthPrefix public (it is currently private, but the source is available).

Just write each object to file after you have created it - job done.

If you want an example, please say - although the unit tests here give an overview.

It would basically be something like (untested):

using(Stream s = File.Create(path))
{
    Serializer.SerializeWithLengthPrefix(s, command1, PrefixStyle.Base128, 0);
    ... your code etc
    Serializer.SerializeWithLengthPrefix(s, commandN, PrefixStyle.Base128, 0);
}
...
using(Stream s = File.OpenRead(path)) {
    foreach(Command command in
           Serializer.DeserializeItems<Command>(s, PrefixStyle.Base128, 0))
    {
       ... do something with command
    }
}
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • I know I am late for the party but do you mind elaborating on *`BinaryFormatter is very brittle to begin with - I don't recommend it in most cases.`* Why is it brittle? Why you don't recommend it? It's been a while since this answer maybe you can recommend another way to serialize multiple objects into a single file/multiple file? –  May 23 '14 at 08:43
  • 1
    @mehow sure: BinaryFormatter is very version/refactor intolerant: it is very easy to cause it to not be able to deserialize existing files when changing... well, anything frankly. It is also framework and platform dependent, restricting options. It is also unnecessarily bloated and inefficient, and has a number of "gotchas". As for your other question: i an biased, but I would say that protobuf-net addresses all of these. That was, after all, the design goal :) protobuf-net is perfectly happy with multiple objects in a stream, as long as the *WithLengthPrefix methods are used. – Marc Gravell May 23 '14 at 08:50
  • Straight from https://code.google.com/p/protobuf-net/ : "The .proto serialization format is a credit to Google's ingenuity. This specific .NET implementation is designed and written by Marc Gravell, developer for Stack Exchange / Stack Overflow."... If you developed it then i think that your opinion is "subjective" not "objective" – lauCosma Jun 17 '14 at 17:20
  • 1
    @lauCosma that depends on what opinion; I regularly and routinely use multiple serialization formats, and know most of the limitations and target scenarios of many of the formats and (separately) libraries. I would say that this hands on experience qualifies me to some "objective" statements on the pros and cons of each. However, I can't find anywhere in this post where "subjective" or "objective" is mentioned, so it is hard to know what *specifically* you are referring to – Marc Gravell Jun 17 '14 at 18:32
0

See answer here.

In short, just serialize everything to the same file stream, and then deserialize. dotNet would know the size of each object

Community
  • 1
  • 1
Elazar Leibovich
  • 32,750
  • 33
  • 122
  • 169
0

For every object that arrives, we will convert it into a Base64Encoded string and store it as one line in a text file. So, in this file, every row will have a serialized object per line. While reading we will read the file one line at a time and deserialize this Base64 encoded string into our Object. Easy.. so lets try out the code.

http://www.codeproject.com/KB/cs/serializedeserialize.aspx?display=Print