c#从文件反序列化到对象——内存不足

本文关键字:对象 内存不足 反序列化 文件 | 更新日期: 2023-09-27 18:13:39

我发布并回答了一个关于如何将相当大(~150 meg)的对象序列化到文件而不会出现内存不足异常的问题。现在这是可行的。现在我需要将文件反序列化回一个对象。

我在这段代码的缓冲区分配部分得到内存不足的错误。我在想有一种方法可以让我安排流,这样我就不必先读入临时缓冲区,但需要帮助。

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;
}

我用来序列化对象的代码如下

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();
                }
            }
        }
    }
}

c#从文件反序列化到对象——内存不足

不需要将文件读入内存。将流传入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;
}

我想到的解决方案(非常接近Petrov的解决方案)是:

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;
}