XmlSerializer:生成的文件太大了

时间:2015-07-07 14:53:40

标签: c# xml serializer

我在C#中遇到了XML Serializer的问题。我生成的文件(来自链接的列表点云)的大小为30-40 MB。 (60.000顶点)。

我的Visual Studio崩溃大多数时间(vshost32.exe不再工作) 有时我很幸运,而是得到这个图形问题:

enter image description here

如果我重绘我的模型(我使用opengl控件),它会突然显示它的外观。 enter image description here

我猜我的记忆会导致这种情况。反正有可能减小xml文件的大小吗?他为每个标签使用了整行。 (460.000行!)

  <DistanceNeighbours />
  <Vector>
    <X>-8.52</X>
    <Y>51.05</Y>
    <Z>62.56</Z>
  </Vector>

这是我的Serializable + Deserializable函数,希望你能帮助我。

     /// <summary>
    /// Serializes an object.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="serializableObject"></param>
    /// <param name="fileName"></param>
    public void SerializeObject<T>(T serializableObject, string fileName)
    {
        if (serializableObject == null) { return; }

        try
        {
            XmlDocument xmlDocument = new XmlDocument();
            XmlSerializer serializer = new XmlSerializer(serializableObject.GetType());
            using (MemoryStream stream = new MemoryStream())
            {
                serializer.Serialize(stream, serializableObject);
                stream.Position = 0;
                xmlDocument.Load(stream);
                xmlDocument.Save(fileName);
                stream.Close();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Serialize Object Error");
        }
    }

    /// <summary>
    /// Deserializes an xml file into an object list
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="fileName"></param>
    /// <returns></returns>
    public T DeSerializeObject<T>(string fileName)
    {
        if (string.IsNullOrEmpty(fileName)) { return default(T); }

        T objectOut = default(T);

        try
        {
            string attributeXml = string.Empty;

            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(fileName);
            string xmlString = xmlDocument.OuterXml;

            using (StringReader read = new StringReader(xmlString))
            {
                Type outType = typeof(T);

                XmlSerializer serializer = new XmlSerializer(outType);
                using (XmlReader reader = new XmlTextReader(read))
                {
                    objectOut = (T)serializer.Deserialize(reader);
                    reader.Close();
                }

                read.Close();
            }
        }
        catch (Exception ex)
        {
            //Log exception here
        }

        return objectOut;
    }

谢谢,

3 个答案:

答案 0 :(得分:1)

二进制序列化怎么样?

 BinarySerializer serializer = new BinarySerializer (outType);

BinarySerializer旨在减少文件大小和计算需求的问题。

您可以将结果存储在文件中,在数据库中,然后发送到网络中。

您需要一个二进制反序列化器来备份您的对象。

答案 1 :(得分:0)

使用大型文件(甚至更小)时,如果您不需要通过添加节点,验证架构,应用XPath来处理XmlDocument对象,请考虑使用简单的XmlReader代替。

只需实例化XmlReader类并调用XmlReader.Read()方法。通过检查XmlReader.NodeType属性,您必须在每次读取后定义标记类型。 一旦找到具有属性的特定元素 - 您就可以创建Vector对象(甚至手动)。

在这种情况下,您将获得快速,内存有效的解决方案。比将所有内容加载到XmlDocument中更快。

例如,查看here

答案 2 :(得分:0)

如果你想减轻处理这么大的文件的问题,那么停止将整个序列化的XML加载到内存中,然后在序列化和反序列化时加载到XML DOM中 - 我无法看到它用于任何事情。 XmlDocument可能至少占内存量的10倍(内存中也是如此),因此在尝试这样做时你可能会使用100兆字节。

以下代码应该提供相同的结果(虽然不会影响您的文件大小),但您不会遇到导致锁定和性能问题的内存压力:

public void SerializeObject<T>(T serializableObject, string fileName)
{
    if (serializableObject == null) return;

    var serializer = new XmlSerializer(serializableObject.GetType());

    using (var stream = File.Open(fileName, FileMode.Create))
    {
        serializer.Serialize(stream, serializableObject);
    }
}

public T DeserializeObject<T>(string fileName)
{
    if (string.IsNullOrEmpty(fileName)) return default(T);

    var serializer = new XmlSerializer(typeof(T));

    using (var stream = File.Open(fileName, FileMode.Open))
    {            
        return (T) serializer.Deserialize(stream);
    }
}

减少文件大小的选项?压缩输出(XML 非常可压缩)或更改序列化格式。