C# 附加到序列化集合

C# 附加到序列化集合,c#,optimization,memory,serialization,C#,Optimization,Memory,Serialization,我有一个某种类型的序列化数组。 有没有一种方法可以将新对象附加到此序列化数组(以序列化形式),而无需将已保存的集合读入内存 例如: 我在file.xml中有一个xml序列化的实体数组,包含10^12个元素。我需要向序列化文件中再添加10^5个元素,但我不想读取以前的所有元素,附加新元素并向流中写入新数组,因为这会占用大量资源(尤其是内存) 如果它需要一个二进制序列化程序,我不会有任何问题。通常,解决方案是更改XML字节的大小,这样您就不必像在反序列化时那样读取所有内容 一般的步骤是: 列表项 打

我有一个某种类型的序列化数组。 有没有一种方法可以将新对象附加到此序列化数组(以序列化形式),而无需将已保存的集合读入内存

例如:

我在file.xml中有一个xml序列化的实体数组,包含10^12个元素。我需要向序列化文件中再添加10^5个元素,但我不想读取以前的所有元素,附加新元素并向流中写入新数组,因为这会占用大量资源(尤其是内存)


如果它需要一个二进制序列化程序,我不会有任何问题。

通常,解决方案是更改XML字节的大小,这样您就不必像在反序列化时那样读取所有内容

一般的步骤是:

  • 列表项
  • 打开文件流
  • 存储数组的结束节点
  • 序列化新项
  • 将序列化的字节写入流
  • 写入结束节点
  • 将整数添加到序列化数组的代码示例:

    // Serialize array - in you case it the stream you read from file.xml
    var ints = new[] { 1, 2, 3 };
    var arraySerializer = new XmlSerializer(typeof(int[]));
    var memoryStream = new MemoryStream(); // File.OpenWrite("file.xml")
    arraySerializer.Serialize(new StreamWriter(memoryStream), ints);
    
    // Save the closing node
    int sizeOfClosingNode = 13; // In this case: "</ArrayOfInt>".Length
                                // Change the size to fit your array
                                // e.g. ("</ArrayOfOtherType>".Length)
    
    // Set the location just before the closing tag
    memoryStream.Position = memoryStream.Length - sizeOfClosingNode;
    
    // Store the closing tag bytes
    var buffer = new byte[sizeOfClosingNode];
    memoryStream.Read(buffer, 0, sizeOfClosingNode);
    
    // Set back to location just before the closing tag.
    // In this location the new item will be written.
    memoryStream.Position = memoryStream.Length - sizeOfClosingNode;
    
    // Add to serialized array an item
    var itemBuilder = new StringBuilder();
    // Write the serialized item as string to itemBuilder
    new XmlSerializer(typeof(int)).Serialize(new StringWriter(itemBuilder), 4);
    // Get the serialized item XML element (strip the XML document declaration)
    XElement newXmlItem = XElement.Parse(itemBuilder.ToString());
    // Convert the XML to bytes can be written to the file
    byte[] bytes = Encoding.Default.GetBytes(newXmlItem.ToString());
    // Write new item to file.
    memoryStream.Write(bytes, 0, bytes.Length);
    // Write the closing tag.
    memoryStream.Write(buffer, 0, sizeOfClosingNode);
    
    // Example that it works
    memoryStream.Position = 0;
    var modifiedArray = (int[]) arraySerializer.Deserialize(memoryStream);
    CollectionAssert.AreEqual(new[] { 1, 2, 3, 4 }, modifiedArray);
    
    //序列化数组-在您的例子中,它是从file.xml读取的流
    var ints=new[]{1,2,3};
    var arraySerializer=新的XmlSerializer(typeof(int[]);
    var memoryStream=新的memoryStream();//File.OpenWrite(“File.xml”)
    序列化(新的StreamWriter(memoryStream),ints);
    //保存关闭节点
    int sizeOfClosingNode=13;//在本例中:“.Length”
    //更改大小以适合您的阵列
    //例如(“长度”)
    //在结束标记之前设置位置
    memoryStream.Position=memoryStream.Length-SizeOffClosingNode;
    //存储结束标记字节
    var buffer=新字节[sizeOfClosingNode];
    memoryStream.Read(缓冲区,0,SizeOffClosingNode);
    //设置回关闭标记之前的位置。
    //在此位置将写入新项目。
    memoryStream.Position=memoryStream.Length-SizeOffClosingNode;
    //向序列化数组中添加项
    var itemBuilder=新的StringBuilder();
    //将序列化项作为字符串写入itemBuilder
    新的XmlSerializer(typeof(int)).Serialize(新的StringWriter(itemBuilder),4);
    //获取序列化的itemXML元素(去掉XML文档声明)
    XElement newXmlItem=XElement.Parse(itemBuilder.ToString());
    //将XML转换为可以写入文件的字节
    byte[]bytes=Encoding.Default.GetBytes(newXmlItem.ToString());
    //将新项目写入文件。
    memoryStream.Write(字节,0,字节.长度);
    //写下结束标记。
    memoryStream.Write(缓冲区,0,SizeOffClosingNode);
    //这是一个成功的例子
    memoryStream.Position=0;
    var modifiedArray=(int[])arraySerializer.Deserialize(memoryStream);
    AreEqual(新[{1,2,3,4},modifiedArray);
    
    一般来说,解决方案是更改XML字节的大小,这样您就不必像在反序列化时那样读取所有内容

    一般的步骤是:

  • 列表项
  • 打开文件流
  • 存储数组的结束节点
  • 序列化新项
  • 将序列化的字节写入流
  • 写入结束节点
  • 将整数添加到序列化数组的代码示例:

    // Serialize array - in you case it the stream you read from file.xml
    var ints = new[] { 1, 2, 3 };
    var arraySerializer = new XmlSerializer(typeof(int[]));
    var memoryStream = new MemoryStream(); // File.OpenWrite("file.xml")
    arraySerializer.Serialize(new StreamWriter(memoryStream), ints);
    
    // Save the closing node
    int sizeOfClosingNode = 13; // In this case: "</ArrayOfInt>".Length
                                // Change the size to fit your array
                                // e.g. ("</ArrayOfOtherType>".Length)
    
    // Set the location just before the closing tag
    memoryStream.Position = memoryStream.Length - sizeOfClosingNode;
    
    // Store the closing tag bytes
    var buffer = new byte[sizeOfClosingNode];
    memoryStream.Read(buffer, 0, sizeOfClosingNode);
    
    // Set back to location just before the closing tag.
    // In this location the new item will be written.
    memoryStream.Position = memoryStream.Length - sizeOfClosingNode;
    
    // Add to serialized array an item
    var itemBuilder = new StringBuilder();
    // Write the serialized item as string to itemBuilder
    new XmlSerializer(typeof(int)).Serialize(new StringWriter(itemBuilder), 4);
    // Get the serialized item XML element (strip the XML document declaration)
    XElement newXmlItem = XElement.Parse(itemBuilder.ToString());
    // Convert the XML to bytes can be written to the file
    byte[] bytes = Encoding.Default.GetBytes(newXmlItem.ToString());
    // Write new item to file.
    memoryStream.Write(bytes, 0, bytes.Length);
    // Write the closing tag.
    memoryStream.Write(buffer, 0, sizeOfClosingNode);
    
    // Example that it works
    memoryStream.Position = 0;
    var modifiedArray = (int[]) arraySerializer.Deserialize(memoryStream);
    CollectionAssert.AreEqual(new[] { 1, 2, 3, 4 }, modifiedArray);
    
    //序列化数组-在您的例子中,它是从file.xml读取的流
    var ints=new[]{1,2,3};
    var arraySerializer=新的XmlSerializer(typeof(int[]);
    var memoryStream=新的memoryStream();//File.OpenWrite(“File.xml”)
    序列化(新的StreamWriter(memoryStream),ints);
    //保存关闭节点
    int sizeOfClosingNode=13;//在本例中:“.Length”
    //更改大小以适合您的阵列
    //例如(“长度”)
    //在结束标记之前设置位置
    memoryStream.Position=memoryStream.Length-SizeOffClosingNode;
    //存储结束标记字节
    var buffer=新字节[sizeOfClosingNode];
    memoryStream.Read(缓冲区,0,SizeOffClosingNode);
    //设置回关闭标记之前的位置。
    //在此位置将写入新项目。
    memoryStream.Position=memoryStream.Length-SizeOffClosingNode;
    //向序列化数组中添加项
    var itemBuilder=新的StringBuilder();
    //将序列化项作为字符串写入itemBuilder
    新的XmlSerializer(typeof(int)).Serialize(新的StringWriter(itemBuilder),4);
    //获取序列化的itemXML元素(去掉XML文档声明)
    XElement newXmlItem=XElement.Parse(itemBuilder.ToString());
    //将XML转换为可以写入文件的字节
    byte[]bytes=Encoding.Default.GetBytes(newXmlItem.ToString());
    //将新项目写入文件。
    memoryStream.Write(字节,0,字节.长度);
    //写下结束标记。
    memoryStream.Write(缓冲区,0,SizeOffClosingNode);
    //这是一个成功的例子
    memoryStream.Position=0;
    var modifiedArray=(int[])arraySerializer.Deserialize(memoryStream);
    AreEqual(新[{1,2,3,4},modifiedArray);
    
    这个问题很难回答。“XML序列化数组”是什么?只是一个包含根元素和许多子元素的XML文件,没有其他层次结构?问题完全取决于数据的结构,关于它的详细信息很少。使用IFormatter.Serialize()序列化的类的数组。实际上,序列化程序的类型并不重要。出于性能方面的考虑,我以后可能会使用二进制的。“XML序列化数组”是什么?只是一个包含根元素和许多子元素的XML文件,没有其他层次结构?问题完全取决于数据的结构,关于它的详细信息很少。使用IFormatter.Serialize()序列化的类的数组。实际上,序列化程序的类型并不重要。出于性能方面的考虑,我以后可能会使用二进制的。嗨,Elisha,这似乎是一个非常有趣的答案,我对此投了赞成票。对于像我这样在这方面没有太多经验的人来说,这会有所帮助