7

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

1 Answer 1

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Great, thanks. And tidied up my code at no extra cost! The Base64 conversion demonstrates the perils of copying other bits of your code and re-using them without reading them properly.

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.