I've got a List of Types that I need to save to file and read it after.
I use DataContractSerializer
but I get an exception during deserialization:
Can't find constructor with arguments (SerializationInfo, StreamingContext) in ISerializable "System.RuntimeType".
I've added System.RuntimeType
as a known type to my serializer, but it didn't help.
Here's code of my two methods
public static void SaveTypes(List<Type> types, string fileName)
{
Type rt = types[0].GetType();
List<Type> knownTypes = new List<Type>() { rt }; //I get a List with System.RuntimeType item here
DataContractSerializer serializer = new DataContractSerializer(typeof(List<Type>), knownTypes);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
Stream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write);
using (XmlWriter xw = XmlWriter.Create(fs, settings))
serializer.WriteObject(xw, types);
}
Serialization seems to work fine, and the output file is ok, but problem starts on deserializing:
public static object LoadTypes(string fileName)
{
Stream file = new FileStream(fileName, FileMode.Open, FileAccess.Read);
byte[] data = new byte[file.Length];
file.Read(data, 0, (int)file.Length);
Type rt = file.GetType();
List<Type> knownTypes = new List<Type>() { rt.GetType() };
DataContractSerializer deserializer = new DataContractSerializer(typeof(List<Type>), knownTypes);
Stream stream = new MemoryStream();
stream.Write(data, 0, data.Length);
stream.Position = 0;
return deserializer.ReadObject(stream); //exception here
}
Is there any way to go through this? Or maybe there's some other way to store types?
Serialization is a mechanism of converting the state of an object into a byte stream. Deserialization is the reverse process where the byte stream is used to recreate the actual Java object in memory.
Basic and custom serialization Binary and XML serialization can be performed in two ways, basic and custom.
Thanks! Well, no, because you can only serialize objects, and you can't create an instance of an abstract class.
Marc Gravell is right, you probably should be serializing the data and not the types.
But for some reason, if you really want to serialize the types themselves, then you shouldn't serialize the Type object (pretty sure it's not serailizable). Anyway, serialize Type.FullName
instead. When you load the Types, use Type.Load
public static void SaveTypes(IEnumerable<Type> types, string filename)
{
using (var fs = File.Open(filename, FileMode.OpenOrCreate)
new XmlSerializer(typeof(string[]))
.Serialize(fs, types.Select(t => t.FullName).ToArray())
}
public static IEnumerable<Type> LoadTypes(string filename)
{
using (var fs = File.Open(filename, FileMode.Open)
{
var typeNames = (string[])
new XmlSerializer(typeof(string[]))
.Deserialize(fs);
return typeNames.Select(t => Type.Load(t));
}
}
Note: When working with any Stream
(or really any IDisposable
) you have to either call the Dispose
method or use the using
statement (as I did above). This ensures that the IDisposable
is properly cleaned up (ie releases File System handles).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With