SerializationException was unhandled: The input stream is not a valid binary format. The starting contents (in bytes) are
really stuck, any help and/or comments would be greatly appreciated!
I've written a database program that needs to be able to load contents from a file into a list. So basically i'm trying to use serialization and deserialization for this. The area where the error occurs is in bold and 开发者_运维技巧is italicized:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace ConsoleApplication1
{
class TheFile
{
//Version 1 serialiser, instance specific, so a bit of a pain
public void SerializeObject(string filename, TheDocument document)
{
Stream stream = File.Open(filename, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, document);
stream.Close();
}
public TheDocument DeSerializeObject(string filename)
{
TheDocument document;
Stream stream = File.Open(filename, FileMode.Open);
BinaryFormatter bFormatter = new BinaryFormatter();
***document = (TheDocument)bFormatter.Deserialize(stream);***
stream.Close();
return document;
}
}
}
The error which i receive is as follows: The input stream is not a valid binary format. The starting contents (in bytes) are: 31-37-2F-30-39-2F-32-30-31-31-20-31-31-3A-30-36-3A ...
I have seen this reported somewhere else recently, and I was unable to find an explanation there either. The code as presented looks like it should be fine (although it would benefit greatly from a few using
statements, but they won't break the success case since you are calling .Close()
).
However! I would also warn that IMO BinaryFormatter
is not a good choice for storage in a database, since that suggests it is desirable to read it back in the future. The fact that BinaryFormatter
is type-dependent makes it very very brittle as you version your application. Any of: creating a new app-version, renaming/adding/removing a field, changing a property to an automatically implemented property, changing .NET version, changing platform, ... could make your data either unreadable, or readable only by adding a lot of custom binder code.
I strongly suggest that you consider using a contract-based serializer instead of BinaryFormatter
; any of: DataContractSerializer
(but not NetDataContractSerializer
), XmlSerializer
, JavascriptSerializer
, JSON.Net. If you want binary for size and performance, then protocol buffers (with several C# implementations, including protobuf-net) is designed (by Google) to be version tolerant, small, and fast. Since that list is also cross-platform, it also means your data is safe if, say, you switch platform to Java, Mono, WinRT (the new windows 8 subsystem), PHP, or anything else. BinaryFormatter
will not work on any of those.
Does this succeed?
var path = "...";
var doc = new TheDocument(...);
SerializeObject(path, doc);
var restored = DeserializedObject(path);
Assert.IsNotNull(restored); // NUnit check; use appropriate code
Too big for a comment
精彩评论