Reputation: 647
I posted and answered a question about how to serialize a rather large (~150 meg) object to a file without getting an out-of-memory exception. That now works. Now I need to deserialize the file back into an object.
I am getting an out of memory error at the buffer allocation part of this code. I'm thinking there is a way I can get the streams arranged so I don't have to read into a temporary buffer first, but need help.
public static object Deserialize(Type objType, FileInfo xmlDocFile)
{
object returnValue = null;
if (xmlDocFile != null && objType != null && xmlDocFile.Exists)
{
DataContractSerializer formatter = new DataContractSerializer(objType);
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = null;
using (FileStream textFile = new FileStream(xmlDocFile.FullName, FileMode.Open))
{
buffer = new byte[textFile.Length]; // Out-of-memory thrown here
textFile.Read(buffer, 0, buffer.Length);
}
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(buffer, new XmlDictionaryReaderQuotas());
returnValue = formatter.ReadObject(reader, true);
}
return returnValue;
}
The code I use to serialize the object is this
public static void Serialize(object obj, FileInfo destination)
{
if (null != obj)
{
using (TextWriter writer = new StreamWriter(destination.FullName, false))
{
XmlTextWriter xmlWriter = null;
try
{
xmlWriter = new XmlTextWriter(writer);
DataContractSerializer formatter = new DataContractSerializer(obj.GetType());
formatter.WriteObject(xmlWriter, obj);
}
finally
{
if (xmlWriter != null)
{
xmlWriter.Flush();
xmlWriter.Close();
}
}
}
}
}
Upvotes: 0
Views: 864
Reputation: 647
The solution I came up with (which is very close to the one by Petrov) is:
public static object Deserialize(Type objType, FileInfo xmlDocFile)
{
object returnValue = null;
if (xmlDocFile != null && objType != null && xmlDocFile.Exists)
{
DataContractSerializer formatter = new DataContractSerializer(objType);
using (FileStream fs = File.Open(xmlDocFile.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (BufferedStream bs = new BufferedStream(fs))
{
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(bs, Encoding.UTF8, new XmlDictionaryReaderQuotas(), null);
returnValue = formatter.ReadObject(reader, true);
}
}
}
return returnValue;
}
Upvotes: 0
Reputation: 14231
No need to read the file into memory. Pass the stream into the DataContractSerializer
.
public static object Deserialize(Type objType, FileInfo xmlDocFile)
{
object returnValue = null;
if (xmlDocFile != null && objType != null && xmlDocFile.Exists)
{
DataContractSerializer formatter = new DataContractSerializer(objType);
using (FileStream textFile = new FileStream(xmlDocFile.FullName, FileMode.Open))
{
returnValue = formatter.ReadObject(textFile);
}
}
return returnValue;
}
Upvotes: 1