C# 如何将二进制数据附加到XML文件中特定位置的特定节点

C# 如何将二进制数据附加到XML文件中特定位置的特定节点,c#,.net,xml,linq-to-xml,C#,.net,Xml,Linq To Xml,我们使用XML文件来保存我们的数据,这些数据都是双重的。由于我们的数据非常庞大,在GB范围内,因此我们将其转换为字节,以节省磁盘空间和访问时间。此外,我们正在以几MB的数据块编写数据,新的数据块也可以来自与前一个数据块相同的源,也可以来自不同的源。对于每个新的源,我们都在XML文件中创建了一个元素,以便将来轻松地识别来自该源的数据。 我们面临的问题是,如何在XML文件中标识与源相对应的元素,然后将与该源相对应的数据附加到XML文件中已经捕获的数据中。我正在使用LINQtoXML,无法使用此方法搜

我们使用XML文件来保存我们的数据,这些数据都是双重的。由于我们的数据非常庞大,在GB范围内,因此我们将其转换为字节,以节省磁盘空间和访问时间。此外,我们正在以几MB的数据块编写数据,新的数据块也可以来自与前一个数据块相同的源,也可以来自不同的源。对于每个新的源,我们都在XML文件中创建了一个元素,以便将来轻松地识别来自该源的数据。
我们面临的问题是,如何在XML文件中标识与源相对应的元素,然后将与该源相对应的数据附加到XML文件中已经捕获的数据中。我正在使用LINQtoXML,无法使用此方法搜索任何解决方案。我尝试使用XMLWriter类,但使用它的问题是如何识别或到达要为其写入区块的元素。

XML不是写入大量二进制数据的好格式(因为需要将二进制数据存储为Base64字符串或其他一些字符串安全编码)也不适合在大文档的中间更新数据块。我建议重新考虑你的文件格式

如果必须使用XML:

  • 确保写入XML时字节数组是Base64编码的
  • <> LI>当要在中间插入数据时,必须复制XML。考虑使用XMLRead和XMLWrror。将源XML复制到您要添加数据的位置,将数据添加到输出编写器,然后完成XML其余部分的复制
  • 避免在内存中加载整个XML,因为它会导致GB范围的数据出现问题
我肯定这里没有完整的情况,但很难理解为什么不使用数据库来实现这一点。尽管如此,为了跟进Alexei的文章,这里有一个精心设计的示例,说明如何使用XmlReader和XmlWriter来完成我认为您想要做的事情:

//start with some dummy data
string bigData = "<bigdata><rec id='1'>1234</rec><rec id='2'>2468</rec></bigdata>";
string criterion = "2";
string append = "10";
string newValue = "";
bool match = false;
StringBuilder sb = new StringBuilder();
using (XmlWriter writer = XmlWriter.Create(sb))
{
    using (XmlReader reader = XmlReader.Create(new StringReader(bigData)))
    {
    while (reader.Read())
    {
    switch (reader.NodeType)
    {
    case XmlNodeType.Element:
        if (reader.LocalName == "rec")
        {
            match = reader.GetAttribute("id").ToString() == criterion;
        }
        writer.WriteStartElement(reader.LocalName);
        writer.WriteAttributes(reader, true);
        if (reader.IsEmptyElement)
        {
            writer.WriteEndElement();
        }
        break;
    case XmlNodeType.Text: // do the append here
        newValue = match ? reader.Value + append : reader.Value;
        writer.WriteString(newValue);
        break;
    //other cases based on node types
    case XmlNodeType.EndElement:
        writer.WriteFullEndElement();
        break;
    }                                                                      
    }
        writer.Flush();
        string x = sb.ToString();//output
    }                         
}
//从一些伪数据开始
字符串bigData=“12342468”;
字符串条件=“2”;
字符串append=“10”;
字符串newValue=“”;
布尔匹配=假;
StringBuilder sb=新的StringBuilder();
使用(XmlWriter=XmlWriter.Create(sb))
{
使用(XmlReader=XmlReader.Create(新建StringReader(bigData)))
{
while(reader.Read())
{
开关(reader.NodeType)
{
case XmlNodeType.Element:
如果(reader.LocalName==“rec”)
{
match=reader.GetAttribute(“id”).ToString()==条件;
}
writer.writeStarteElement(reader.LocalName);
作者、作者、赞词(读者、真实);
if(读卡器ISemptyelment)
{
writer.writeedelement();
}
打破
case XmlNodeType.Text://在此处追加
newValue=match?reader.Value+append:reader.Value;
writer.WriteString(newValue);
打破
//基于节点类型的其他情况
案例XmlNodeType.EndElement:
writer.writeFileLendElement();
打破
}                                                                      
}
writer.Flush();
字符串x=sb.ToString();//输出
}                         
}
您所说的“将其转换为字节”到底是什么意思?这也是每一条小溪都会做的。