0

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++.

4 Answers 4

1

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);
}
Sign up to request clarification or add additional context in comments.

2 Comments

you need to serialize a list of objects so that the deserialization give you back the same list of objects :dotnetperls.com/serialize-list
@user3290807 Not sure you have to - you can certainly read consecutive objects from a stream. It makes the deserialization easier (as you just deserialize the list rather than looping) but it's not required.
0

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.

Comments

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

1 Comment

Please provide more specific answer, not just some bunch of code lines
0

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

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.