XML Serialize - BIG Data(20GB),OutOfMemoryException

时间:2017-05-15 10:52:34

标签: c# xml serialization out-of-memory

我有一个问题:我想序列化一个xml(20GB),但我得到一个out of memory例外。

你有什么建议吗?

我的代码如下:

public static string Serialize(object obj)
{
    string retval = string.Empty;

    if (null!= obj)
    {
        StringBuilder sb = new StringBuilder();
        using (XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings() { OmitXmlDeclaration = true }))
        {                    
            XmlSerializer serializer = new XmlSerializer(obj.GetType());

            // We are ommitting the namespace to simplifying passing as parameter
            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
            ns.Add("", "");

            serializer.Serialize(writer, obj);
        }

        retval = sb.ToString();
    }
    return retval;
}

2 个答案:

答案 0 :(得分:3)

20 GB 永远不会作为string工作(通过StringBuilder);即使启用<gcAllowVeryLargeObjects>string的最大理论长度也只是其中的一小部分。

如果您需要大量数据,则需要使用类似文件(或基本上:Stream而非MemoryStream)作为后端。

我还会说xml是大数据的可怕选择。如果您没有与xml紧密绑定,我强烈建议您查看其他工具(如果可以选择,我很乐意提供建议)。

但是现在:

string path = "my.xml";
XmlWriterSettings settings = ...
using (XmlWriter writer = XmlWriter.Create(path, settings))
{
    // ...
}

或者如果您实际上正在与套接字等进行交谈:

Stream stream = ...
XmlWriterSettings settings = ...
using (XmlWriter writer = XmlWriter.Create(stream, settings))
{
    // ...
}

答案 1 :(得分:0)

你可能有一个List来分块

        public static void Serialize(List<MyClass> myClasses)
        {
            string retval = string.Empty;

            if (myClasses != null)
            {

                using (StreamWriter sWriter = new StreamWriter("filename", false))
                {
                    foreach (MyClass myClass in myClasses)
                    {

                        StringBuilder sb = new StringBuilder();
                        using (XmlWriter writer1 = XmlWriter.Create(sb, new XmlWriterSettings() { OmitXmlDeclaration = true }))
                        {
                            XmlSerializer serializer = new XmlSerializer(myClass.GetType());

                            // We are ommitting the namespace to simplifying passing as parameter
                            XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                            ns.Add("", "");

                            serializer.Serialize(writer1, myClass);
                        }
                        sWriter.Write(sb.ToString());

                    }

                }
            }
        }