C#大型复杂对象反序列化

C#大型复杂对象反序列化,c#,xml,serialization,deserialization,xml-deserialization,C#,Xml,Serialization,Deserialization,Xml Deserialization,我现在真的不知道该怎么办了,我搜索了整个互联网,尝试了很多东西,但我无法将我的对象反序列化为类 首先,我将向您介绍我的数据结构: [Serializable] [XmlRoot("Plugin")] public class SiXmlPlugin { [XmlAttribute("Name")] public string Name { get; set; } [XmlAttribute("Version")] public long Version { ge

我现在真的不知道该怎么办了,我搜索了整个互联网,尝试了很多东西,但我无法将我的对象反序列化为类

首先,我将向您介绍我的数据结构:

[Serializable]
[XmlRoot("Plugin")]
public class SiXmlPlugin
{
    [XmlAttribute("Name")]
    public string Name { get; set; }

    [XmlAttribute("Version")]
    public long Version { get; set; }

    [XmlAttribute("VersionString")]
    public String VersionString { get; set; }

    [XmlElement("Files")]
    public List<SiFile> Files = new List<SiFile>();

    [XmlElement("Folders")]
    public List<SiFolder> Folders = new List<SiFolder>();
}

[Serializable]
[XmlRoot("Folder")]
public class SiFolder
{
    [XmlAttribute("Name")]
    public string Name { get; set; }

    [XmlElement("Files")]
    public List<SiFile> Files = new List<SiFile>();

    [XmlElement("Folders")]
    public List<SiFolder> Folders = new List<SiFolder>();
}

[Serializable]
[XmlRoot("File")]
public class SiFile
{
    [XmlAttribute("Filename")]
    public string Filename { get; set; }

    [XmlElement("Content")]
    public string Content { get; set; }
}
[可序列化]
[XmlRoot(“插件”)]
公共类插件
{
[XmlAttribute(“名称”)]
公共字符串名称{get;set;}
[XmlAttribute(“版本”)]
公共长版本{get;set;}
[XmlAttribute(“VersionString”)]
公共字符串版本字符串{get;set;}
[XmlElement(“文件”)]
公共列表文件=新列表();
[XmlElement(“文件夹”)]
公共列表文件夹=新列表();
}
[可序列化]
[XmlRoot(“文件夹”)]
公共类筛选器
{
[XmlAttribute(“名称”)]
公共字符串名称{get;set;}
[XmlElement(“文件”)]
公共列表文件=新列表();
[XmlElement(“文件夹”)]
公共列表文件夹=新列表();
}
[可序列化]
[XmlRoot(“文件”)]
公共类SiFile
{
[XmlAttribute(“文件名”)]
公共字符串文件名{get;set;}
[XmlElement(“内容”)]
公共字符串内容{get;set;}
}
这是我的三节课。 我正在尝试反序列化一个SiXmlPlugin对象。 如你所见,结构相当复杂。 序列化文件的大小为480 mb,因此它相当大

对象的序列化工作正常。 但是当我反序列化它时,我总是得到一个OutOfMemoryException。 我尝试了Xml、Binaryserializer和protobuf net,但所有这些方法都得到了相同的异常

我知道结构不是很好,但在这种情况下,它是必要的。 不管怎样,有人知道如何解决这个问题吗? 我真的被这种情况困住了


提前感谢:)

如果文件太大,无法放入内存,请尝试在读取时对其进行处理,而不是立即完全加载。您可以使用
XmlReader
实现它。您可以找到如何使用它的示例。

查看以下代码是否有效。还没有机会对代码进行全面测试,但它似乎可以工作。我生成了自己的xml,但不确定它是否与您的完全相同。我也没有添加contents属性

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace ConsoleApplication45
{
    class Program
    {
        const string READFILENAME = @"c:\temp\test.xml";
        const string FOLDER = @"c:\temp";
        static void Main(string[] args)
        {

            //new Write(FOLDER, READFILENAME);
            new SiXmlPlugin(READFILENAME);
        }


    }

    //[XmlRoot("Plugin")]
    public class SiXmlPlugin
    {
        public static SiXmlPlugin root = null;
        //[XmlAttribute("Name")]
        public string Name { get; set; }

        //[XmlAttribute("Version")]
        public long Version { get; set; }

        //[XmlAttribute("VersionString")]
        public String VersionString { get; set; }

        //[XmlElement("Files")]
        public List<SiFile> Files = new List<SiFile>();

        //[XmlElement("Folders")]
        public List<SiFolder> Folders = new List<SiFolder>();

        public SiXmlPlugin() { }
        public SiXmlPlugin(string filename)
        {

            XmlReader reader = XmlReader.Create(filename);
            reader.ReadToFollowing("Plugin");
            reader.ReadStartElement();
            root = new SiXmlPlugin();
            int depth = reader.Depth;
            ReadFolderRecursive(root.Folders, reader, depth);

        }
        public static void ReadFolderRecursive(List<SiFolder> folders, XmlReader reader, int depth)
        {
            SiFolder newFolder = null;
            while (!reader.EOF)
            {
                XmlNodeType nodeType = reader.NodeType;
                switch (nodeType)
                {
                    case XmlNodeType.Whitespace:
                        reader.Read();
                        break;
                    case XmlNodeType.Element:
                        switch (reader.Name)
                        {
                            case "Files":
                                reader.ReadStartElement();
                                ReadFolderRecursive(folders, reader, reader.Depth); 
                                break;
                            case "File":
                                SiFile newFile = new SiFile();
                                folders.Last().Files.Add(newFile);
                                newFile.Filename = reader.GetAttribute("Name");
                                reader.ReadStartElement();

                                break;
                            case "Folders":
                                int newDepth = reader.Depth;
                                if (newDepth < depth) return;

                                if (newDepth == depth)
                                {
                                    newFolder = new SiFolder();
                                    newFolder.Name = reader.GetAttribute("Name");
                                    folders.Add(newFolder);
                                    reader.ReadStartElement();
                                }
                                else
                                {

                                   if (newFolder.Folders == null)
                                    {
                                        newFolder.Folders = new List<SiFolder>();
                                   }
                                   ReadFolderRecursive(newFolder.Folders, reader, newDepth);
                                }
                                break;
                            default:
                                reader.ReadStartElement();
                                break;
                        }

                        break;
                    case XmlNodeType.Attribute:

                        break;
                    default:
                        reader.Read();
                        break;
                }
            }
        }


    //[XmlRoot("Folder")]
    public class SiFolder
    {
        //[XmlAttribute("Name")]
        public string Name { get; set; }

        //[XmlElement("Files")]
        public List<SiFile> Files = new List<SiFile>();

        //[XmlElement("Folders")]
        public List<SiFolder> Folders = new List<SiFolder>();

        }
    }

    //[XmlRoot("File")]
    public class SiFile
    {
        //[XmlAttribute("Filename")]
        public string Filename { get; set; }

        //[XmlElement("Content")]
        public string Content { get; set; }
    }


    public class Write
    {
        static XmlWriter writer = null;

        public Write(string folderName,string readFilename)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;

            writer = XmlWriter.Create(readFilename, settings);
            writer.WriteStartDocument(true);

            writer.WriteStartElement("Plugin");

            DirectoryInfo info = new DirectoryInfo(folderName);
            WriteTree(info);

            writer.WriteEndElement();

            writer.WriteEndDocument();
            writer.Flush();
            writer.Close();
            Console.WriteLine("Enter Return");
            Console.ReadLine();
        }
        static long WriteTree(DirectoryInfo info)
        {
            long size = 0;
            writer.WriteStartElement("Folders");
            try
            {
                writer.WriteAttributeString("Name", info.Name);
                writer.WriteAttributeString("NumberSubFolders", info.GetDirectories().Count().ToString());
                writer.WriteAttributeString("NumberFiles", info.GetFiles().Count().ToString());
                writer.WriteAttributeString("Date", info.LastWriteTime.ToString());


                foreach (DirectoryInfo childInfo in info.GetDirectories())
                {
                    size += WriteTree(childInfo);
                }

            }
            catch (Exception ex)
            {
                string errorMsg = string.Format("Exception Folder : {0}, Error : {1}", info.FullName, ex.Message);
                Console.WriteLine(errorMsg);
                writer.WriteElementString("Error", errorMsg);
            }

            FileInfo[] fileInfo = null;
            try
            {
                fileInfo = info.GetFiles();
            }
            catch (Exception ex)
            {
                string errorMsg = string.Format("Exception FileInfo : {0}, Error : {1}", info.FullName, ex.Message);
                Console.WriteLine(errorMsg);
                writer.WriteElementString("Error", errorMsg);
            }

            if (fileInfo != null)
            {
                writer.WriteStartElement("Files");
                foreach (FileInfo finfo in fileInfo)
                {
                    try
                    {
                        writer.WriteStartElement("File");
                        writer.WriteAttributeString("Name", finfo.Name);
                        writer.WriteAttributeString("Size", finfo.Length.ToString());
                        writer.WriteAttributeString("Date", info.LastWriteTime.ToString());
                        writer.WriteEndElement();
                        size += finfo.Length;
                    }
                    catch (Exception ex)
                    {
                        string errorMsg = string.Format("Exception File : {0}, Error : {1}", finfo.FullName, ex.Message);
                        Console.WriteLine(errorMsg);
                        writer.WriteElementString("Error", errorMsg);
                    }
                }
                writer.WriteEndElement();
            }

            writer.WriteElementString("size", size.ToString());
            writer.WriteEndElement();
            return size;

        }
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
使用System.IO;
命名空间控制台应用程序45
{
班级计划
{
常量字符串READFILENAME=@“c:\temp\test.xml”;
常量字符串文件夹=@“c:\temp”;
静态void Main(字符串[]参数)
{
//新写入(文件夹,读取文件名);
新的SiXmlPlugin(READFILENAME);
}
}
//[XmlRoot(“插件”)]
公共类插件
{
公共静态SiXmlPlugin root=null;
//[XmlAttribute(“名称”)]
公共字符串名称{get;set;}
//[XmlAttribute(“版本”)]
公共长版本{get;set;}
//[XmlAttribute(“VersionString”)]
公共字符串版本字符串{get;set;}
//[XmlElement(“文件”)]
公共列表文件=新列表();
//[XmlElement(“文件夹”)]
公共列表文件夹=新列表();
公共SiXmlPlugin(){}
公共插件(字符串文件名)
{
XmlReader=XmlReader.Create(文件名);
reader.ReadToFollow(“插件”);
reader.ReadStartElement();
root=新的SiXmlPlugin();
int-depth=reader.depth;
ReadFolderRecursive(root.Folders、reader、depth);
}
公共静态void ReadFolderRecursive(列表文件夹、XmlReader阅读器、int-depth)
{
SiFolder newFolder=null;
而(!reader.EOF)
{
XmlNodeType-nodeType=reader.nodeType;
开关(节点类型)
{
大小写XmlNodeType.Whitespace:
reader.Read();
打破
case XmlNodeType.Element:
开关(reader.Name)
{
案例“档案”:
reader.ReadStartElement();
ReadFolderRecursive(文件夹、读取器、读取器.Depth);
打破
案例“档案”:
SiFile newFile=新的SiFile();
folders.Last().Files.Add(newFile);
newFile.Filename=reader.GetAttribute(“名称”);
reader.ReadStartElement();
打破
案例“文件夹”:
int newDepth=reader.Depth;
if(newDepth