5

I am making an error logging library which creates a file in a specified location, then saves the error information in that file, which can then be read by a separate tasker program that I intend to write in conjunction with this library.

The way that I'm saving it is in Binary Format (using BinaryFormatter() and FileStream()), where I serialize a class called ErrorEntry into the file and append it to the end of the file. What this means is that I have a series of ErrorEntries back to back. I don't have it as a list because it doesn't seem practicle to have to read all the information into a list from the file, add an entry, then save it back to the file and dump the resources. It seems much more effective to only have to do a single write command, and just store each one as its own object that is serialized.

My problem is that I can find several examples on serializing lists or individual objects, but nothing on multiple - but separate - objects. Although I want to save them as individual objects, when I load them I want to read the object and return the series as a list of that object. I imagine that there is something similar to

while(!EOF)
{
     //deserialize each object
     //add individual object to a list
}
//return the list of objects

How would I go about deserializing each object from a single file? Does it have an internal marker that the above works and I simply need to detect whether it's the end of the file, or do I need to do something else to read them?

David Torrey
  • 1,335
  • 3
  • 20
  • 43
  • Why don't you just put all those objects into a `List` and serialize that data structure? You will prevent lots of corner cases like interdependencies among objects thought to be 'separate'. – Ondrej Tucny May 07 '13 at 10:19
  • @OndrejTucny he wants to append to the file without loading all the previous entries in. – weston May 07 '13 at 10:22
  • He said why and it looks reasonable. To deserialize on object level you must write delimiter sequence after each entry and react on it when you read file back. – Tommi May 07 '13 at 10:22

1 Answers1

6

With FileStream fs; you could do fs.Position!=fs.Length to detect EOF.

When appending, use FileMode.Append or fs.Seek(0, SeekOrigin.End); to go to the end before writting the new entry.

Deserializing in full:

public static ICollection<T> DeserializeList<T>(FileStream fs)
{
    BinaryFormatter bf = new BinaryFormatter();
    List<T> list = new List<T>();
    while(fs.Position!=fs.Length)
    {
         //deserialize each object in the file
         var deserialized = (T)bf.Deserialize(fs); 
         //add individual object to a list
         list.Add(deserialized);
    }
    //return the list of objects
    return list;
}
Community
  • 1
  • 1
weston
  • 54,145
  • 21
  • 145
  • 203
  • 1
    What about deserializing objects back from this file? The fact that you can serialize many objects to the file using append does not guarantee you will be able to deserialize them back. – Artemix May 07 '13 at 10:30
  • @Artemix see edit. Based on his code in question. Is there anything wrong with that? – weston May 07 '13 at 10:37
  • wouldn't just using filemode.append and then writing work? or do i have to say filemode.append and fs.seek? – David Torrey May 07 '13 at 10:49
  • I'll test it out and let you know if everything goes smooth – David Torrey May 07 '13 at 10:55