11

Let say I have a file that contains a serialized object by BinaryFomatter. Now I want to be able to serialize another object and APPEND this on that existing file.

How can I do it?

Canavar
  • 47,715
  • 17
  • 91
  • 122
user50819
  • 333
  • 1
  • 5
  • 14

5 Answers5

21

This is indeed possible. The code below appends the object.

using (var fileStream = new FileStream("C:\file.dat", FileMode.Append))
{
    var bFormatter = new BinaryFormatter();
    bFormatter.Serialize(fileStream, objectToSerialize);
}

The following code de-serializes the objects.

var list = new List<ObjectToSerialize>();    

using (var fileStream = new FileStream("C:\file.dat", FileMode.Open))
{
    var bFormatter = new BinaryFormatter();
    while (fileStream.Position != fileStream.Length)
    {
         list.Add((ObjectToSerialize)bFormatter.Deserialize(fileStream));
    }
}

Note for this to work the file must only contain the same objects.

Magpie
  • 6,983
  • 14
  • 51
  • 67
  • Did you try this code? seems it de-serializes only part that was appended last. here is my test code http://pastebin.com/EV4rPaT4 – mrgloom Jul 08 '13 at 11:42
  • 1
    Hi mrgloom. This is nearly 4 years old but yes it was used in production with no issues. I've had a look at your test code. You're serializing 3 separate lists not appending to one existing one. When you deserialize you override each list object with the latest one. Try changing line 22 to list.AddRange((List)bFormatter.Deserialize(fileStream)); Good luck. – Magpie Jul 08 '13 at 15:33
  • Thanks, it works great! Though I don't know why :/ How can bFormatter.Deserialize know when does an ObjectToSerialize end in the file? while debugging, fileStream.Position stops right at the position where each ObjectToSerialize ends in the file, and I can't figure out why... – Alvaro Rodriguez Scelza Dec 16 '17 at 15:03
4

Put your objects into a collection object and serialize like that. If you'd manage to append a binary representation of an object at the end of an existing file you'd get problems reading it back.

paweloque
  • 18,466
  • 26
  • 80
  • 136
  • I'm sure that's what I just said – tomfanning Apr 29 '09 at 18:29
  • 1
    Sure that's the same. Remind however that it is possible to write an answer simultaneously and post it at almost the same time without seeing the other answers. ;) – paweloque Apr 29 '09 at 18:33
  • None, if the collection of objects is serialised and deserialised. You'll just get a collection back containing the same objects you started with. – tomfanning Apr 29 '09 at 19:21
  • @lassevk You'd be deserializing 1 stream to 2 object types... Which I suppose you could do by deserialize the first x bytes of the stream to object type 1 and then the next y bytes to object type 2. It's a terrible code smell if you ask me. If the objects belong together, they should be together (ie. aggregates of/internal to 1 type). – Steven Evers Apr 29 '09 at 20:28
3

Actually, if you just open the stream for writing, and positioning the pointer at the end of the stream, you can serialize another object and it will be appended to the existing stream.

Deserializing will also read past the object, but not further.

Obviously, if you want random access to your objects (deserialize object nr. 17, but not everything before it), then you need an index of the positions where each object starts, but if you just want to read all objects from the start, you can just serialize them out after each other.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • And how would you deserialize it afterwars? Are you sure .Net knows the serialized object size from the headers? – Elazar Leibovich Apr 29 '09 at 18:35
  • When you think about it, obviously it has to know the size, because it also just serializes sub-objects normally. It would never be able to deserialize such objects if it didn't know the size of them. So either it doesn't need to know the size, or it figures it out as it goes along. – Lasse V. Karlsen Apr 29 '09 at 19:04
2

How's about this

Deserialise the contents of your first file into an object in memory, add the first object to a collection (e.g. List<YourObjectType>), add your new object to that collection, then serialise the collection (containing two objects now) on top of the existing file.

tomfanning
  • 9,552
  • 4
  • 50
  • 78
2

First, if what you really need is to store an array of object - put them in a container and serialize the container, as said earlier.

Now, if you really want to store two serialized object in a single file concatenated:

I'm not sure that this is possible "out of the box", but you can do two things.

  1. Use, or invent your own semi-tar file format, in which you'll write a small header in the beginning (or end) of the file that describes the content of the file (#'objects, and sizes).

  2. Write a C# code to detect the beginning and end of each serialized object yourself. I'm not entirely sure it's possible. Here is a non-official documentation of the serialization format. It contains header, however there's no guarantee that this header won't appear in the file.

Elazar Leibovich
  • 32,750
  • 33
  • 122
  • 169