Waleed Ahmad
Waleed Ahmad

Reputation: 2294

Reading serialized objects from binary file

I'm trying to write and read serialized objects to a binary file. I'm using Append FileMode to add serialized objects but when i try to read the file, it only print a single deserialized object.

Here's my serialization method.

public void serialize(){ 
    MyObject obj = new MyObject();
    obj.n1 = 1;
    obj.n2 = 24;
    obj.str = "Some String";
    IFormatter formatter = new BinaryFormatter();
    Stream stream = new FileStream("MyFile.bin", FileMode.Append,                          FileAccess.Write, FileShare.None);
    formatter.Serialize(stream, obj);
    stream.Close()
}

Here's my deserialization method.

public static void read()
{
    IFormatter formatter = new BinaryFormatter();
    Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
    MyObject obj = (MyObject)formatter.Deserialize(stream);
    stream.Close();

    // Here's the proof.
    Console.WriteLine("n1: {0}", obj.n1);
    Console.WriteLine("n2: {0}", obj.n2);
    Console.WriteLine("str: {0}", obj.str);
}

How can we loop through every single serialized record in file, like we use File.eof() or while(file.read()) in C++.

Upvotes: 0

Views: 4114

Answers (4)

Sanjay ch
Sanjay ch

Reputation: 1

Simply iterate through each object in binary file

using (System.IO.FileStream fs = new System.IO.FileStream("D:\\text\\studentdata.txt", System.IO.FileMode.Open, System.IO.FileAccess.Read))
        {
            System.Runtime.Serialization.Formatters.Binary.BinaryFormatter sf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            Object o = sf.Deserialize(fs);
            while (fs.Position < fs.Length)
            {
                o = sf.Deserialize(fs);
                Student student = (o as Student);
                Console.WriteLine("str: {0}", student.sname);
            }
        }

Upvotes: 0

Thank you for your help, I made this.

    using System.IO;
    using System.Runtime.Serialization.Formatters.Binary;

    private static Dictionary<int, ArrayList> J1_CarteDeck;

    private static string PathDocuments = String.Format("{0}\\Antize Game\\", Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
    private const string FILE_NAME      = "Antize.data";

   public static bool SauvegarderDeck()
   {
       if (!(Directory.Exists(PathDocuments)))
           Directory.CreateDirectory(PathDocuments);

       if (File.Exists(PathDocuments + FILE_Deck))
           File.Delete(PathDocuments + FILE_Deck);

       foreach (ArrayList child in J1_CarteDeck.Values)
       {  
           if(child != null)
           { 
                BinaryFormatter formatter   = new BinaryFormatter();
                FileStream stream           = new FileStream(PathDocuments + FILE_Deck, FileMode.Append, FileAccess.Write, FileShare.None);
                formatter.Serialize(stream, child);
                stream.Close();
            }
        }

        if (File.Exists(PathDocuments + FILE_Deck))
            return true;
        else
            return false;
    }

    public static bool ChargerDeck()
    {
        if (!(File.Exists(PathDocuments + FILE_Deck)))
            return false;

        int cptr = 1;

        J1_CarteDeck                = new Dictionary<int, ArrayList>();

        BinaryFormatter formatter   = new BinaryFormatter();
        Stream stream               = new FileStream(PathDocuments + FILE_Deck, FileMode.Open, FileAccess.Read, FileShare.None);

        while (stream.Position < stream.Length)
        {
            J1_CarteDeck[cptr] = (ArrayList)formatter.Deserialize(stream);
            cptr++;
        }

        stream.Close();

        return true;
    }

Upvotes: 0

fantaztig
fantaztig

Reputation: 116

The explanation above is correct, however I'd put it like this, using a collection of your like:

    public static void serializeIt()
    { 
        MyObject obj = new MyObject();
        obj.n1 = 1;
        obj.n2 = 24;
        obj.str = "Some String";
        MyObject obj2 = new MyObject();
        obj2.n1 = 1;
        obj2.n2 = 24;
        obj2.str = "Some other String";
        List<MyObject> list = new List<MyObject>();
        list.Add(obj);
        list.Add(obj2);
        IFormatter formatter = new BinaryFormatter();
        Stream stream = new FileStream("MyFile.bin", FileMode.Append,FileAccess.Write, FileShare.None);
        formatter.Serialize(stream, list);
        stream.Close();
    }

    public static void read()
    {
        IFormatter formatter = new BinaryFormatter();
        Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
        List<MyObject> list = (List<MyObject>)formatter.Deserialize(stream);
        stream.Close();

    }

You should also make sure that the MyFile.bin is rewriten each time you serialize your collection, as it would always return the collection that was saved first if you'd keep appending them. That should be the only downside.

Upvotes: 0

D Stanley
D Stanley

Reputation: 152521

Deserialize only returns one object. You need to create a collection and loop until the end of the stream is reached:

List<MyObject> list = new List<MyObject>();
Stream stream = new FileStream("MyFile.bin", FileMode.Open, FileAccess.Read, FileShare.Read);
while(stream.Position < stream.Length)
{
     MyObject obj = (MyObject)formatter.Deserialize(stream);
     list.add(obj);
}

Upvotes: 1

Related Questions