Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize Entity Framework object, save to file, read and DeSerialize

The title should make it clear what I'm trying to do - get an Entity Framework object, serialize it into a string, save the string in a file, then load the text from the file and reserialize it into an object. Hey presto!

But of course it doesn't work else I wouldn't be here. When I try to reserialise I get an "The input stream is not in a valid binary format" error so I'm obviously missing something somewhere.

This is how I serialise and save my data:

 string filePath = System.Configuration.ConfigurationManager.AppSettings["CustomersLiteSavePath"];
 string fileName = System.Configuration.ConfigurationManager.AppSettings["CustomersLiteFileName"];

        if(File.Exists(filePath + fileName))
        {
            File.Delete(filePath + fileName);
        }

        MemoryStream memoryStream = new MemoryStream();
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(memoryStream, entityFrameWorkQuery.First());
        string str = System.Convert.ToBase64String(memoryStream.ToArray());

        StreamWriter file = new StreamWriter(filePath + fileName);
        file.WriteLine(str);
        file.Close();

Which gives me a big nonsensical text file, as you'd expect. I then try and rebuild my object elsewhere:

            CustomerObject = File.ReadAllText(path);

            MemoryStream ms = new MemoryStream();
            FileStream fs = new FileStream(path, FileMode.Open);
            int bytesRead;
            int blockSize = 4096;
            byte[] buffer = new byte[blockSize];

            while (!(fs.Position == fs.Length))
            {
                bytesRead = fs.Read(buffer, 0, blockSize);
                ms.Write(buffer, 0, bytesRead);
            }

            BinaryFormatter formatter = new BinaryFormatter();
            ms.Position = 0;
            Customer cust = (Customer)formatter.Deserialize(ms);

And then I get the binary format error.

I'm obviously being very stupid. But in what way?

Cheers, Matt

like image 674
Bob Tway Avatar asked Feb 18 '11 12:02

Bob Tway


1 Answers

When you've saved it, you have (for reasons best known to you) applied base-64 - but you haven't applied base-64 when reading it. IMO, just drop the base-64 completely - and write directly to the FileStream. This also saves having to buffer it in memory.

For example:

    if(File.Exists(path))
    {
        File.Delete(path);
    }
    using(var file = File.Create(path)) {
         BinaryFormatter ser = new BinaryFormatter();
         ser.Serialize(file, entityFrameWorkQuery.First());
         file.Close();
    }

and

     using(var file = File.OpenRead(path)) {
         BinaryFormatter ser = new BinaryFormatter();
         Customer cust = (Customer)ser.Deserialize(file);
         ...
    }     

as a side note, you may find that DataContractSerializer makes a better serializer for EF than BinaryFormatter.

like image 104
Marc Gravell Avatar answered Nov 15 '22 10:11

Marc Gravell