Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将XML直接写入磁盘并附加元素_C#_Xml_C# 4.0_File Io_Xmlwriter - Fatal编程技术网

C# 将XML直接写入磁盘并附加元素

C# 将XML直接写入磁盘并附加元素,c#,xml,c#-4.0,file-io,xmlwriter,C#,Xml,C# 4.0,File Io,Xmlwriter,我试图编写一个XML文件,但它太大,无法存储在内存中,因此我想直接将其写入磁盘。我已经尝试过使用XmlWriter,但是没有能够附加到文件末尾的功能,因此我愿意使用常规的文件编写器来编写XML原始文件 有人知道有哪些文件写入类可以让我直接写入磁盘,并可以覆盖文件中的位置吗 原因是我需要能够在根元素的结尾处进行写操作,以便可以附加另一位信息,但也能够在需要时读取XML文件。例如,如果我有以下XML: <elements> <element> </element

我试图编写一个XML文件,但它太大,无法存储在内存中,因此我想直接将其写入磁盘。我已经尝试过使用XmlWriter,但是没有能够附加到文件末尾的功能,因此我愿意使用常规的文件编写器来编写XML原始文件

有人知道有哪些文件写入类可以让我直接写入磁盘,并可以覆盖文件中的位置吗

原因是我需要能够在根元素的结尾处进行写操作,以便可以附加另一位信息,但也能够在需要时读取XML文件。例如,如果我有以下XML:

<elements>
  <element>
  </element>
</elements>

如果我想读这个,我可以,但是如果我想写它,我必须先删除
标记,附加另一个元素,然后再次附加结束标记


感谢您的帮助。

我认为(正如@payo的评论所建议的那样)您可以使用文件流、an(将流定位到适当的元素)和an的组合来编写新元素,然后重新编写结束元素。

您可以使用XmlTextWriter

只需打开文件进行写入,返回到end元素的开头,然后使用XmlTextWriter追加任何需要的新元素。要关闭该文件,只需为end元素编写原始文本,即可完成文档

这里有一个简单的例子

从XML开始,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<DocumentElement>
    <FirstElem/>
</DocumentElement>
using (FileStream f = new FileStream(@"D:\a.xml", FileMode.OpenOrCreate, FileAccess.Write))
{
    f.Seek(-("</DocumentElement>\n".Length), SeekOrigin.End);
    using (XmlTextWriter x = new XmlTextWriter(f, Encoding.UTF8))
    {
        x.WriteStartElement("Another");
        x.WriteAttributeString("attr", "value");
        x.WriteEndElement();

        // Close the file with a new terminating end-element
        x.WriteRaw("\r\n</DocumentElement>\r\n");
    }
}

您可以打开它并附加如下元素:

<?xml version="1.0" encoding="utf-8"?>
<DocumentElement>
    <FirstElem/>
</DocumentElement>
using (FileStream f = new FileStream(@"D:\a.xml", FileMode.OpenOrCreate, FileAccess.Write))
{
    f.Seek(-("</DocumentElement>\n".Length), SeekOrigin.End);
    using (XmlTextWriter x = new XmlTextWriter(f, Encoding.UTF8))
    {
        x.WriteStartElement("Another");
        x.WriteAttributeString("attr", "value");
        x.WriteEndElement();

        // Close the file with a new terminating end-element
        x.WriteRaw("\r\n</DocumentElement>\r\n");
    }
}
使用(FileStream f=newfilestream(@“D:\a.xml”、FileMode.OpenOrCreate、FileAccess.Write))
{
f、 搜索(“\n”长度),请参见Korigin.End);
使用(XmlTextWriter x=newxmltextwriter(f,Encoding.UTF8))
{
x、 书面声明(“另一份”);
x、 WriteAttributeString(“属性”、“值”);
x、 写删除();
//使用新的终止结束元素关闭文件
x、 WriteRaw(“\r\n\r\n”);
}
}
结果是:

<?xml version="1.0" encoding="utf-8"?>
<DocumentElement>
    <FirstElem/>
<Another attr="value" />
</DocumentElement>

您可能无法获得完美的缩进等,但它是有效的XML。如果将xml作为原始文本写入文件,这正是您要做的——但您也可以利用xml编写器为您进行格式化


我也同意其中的一些评论——为xml使用一个最小化大小的模式将非常有益。关闭缩进。使用尽可能短的元素和属性名称。如果您正在处理叶元素,将数据存储为属性而不是cdata将节省空间(
数据
更昂贵,并且可以进一步压缩到
——几乎是原始大小的一半)

非常不幸的是,XML的设计方式使附加变得不可能。文件有多大?内存限制是什么?我的内存限制是.NET运行时的1.5GB限制,文件非常大。我还没有弄清楚它会有多大,但预计会有很多GB。我想你可以打开一个文件流,搜索到底,构建一个XmlWriter并传递流来创建…这不管用吗?我不得不说,xml似乎不是存储这些数据的最佳方式。是否可以更改模式以缩短标记名(从而减小其大小)?有没有理由它必须是xml文件而不是数据库中的文件?他在问题中明确表示,
XmlWriter
对他不起作用……只需连接流(+1 chris,我想建议这个)@Thomas你是对的,我错了。我已经对它进行了更新,以说明在使用XmlReader和XmlWriter之后如何完成OP。@Chrishain关于XmlReader的观点很好(找到正确的注入点)。我掩饰了那一点。我曾经为一个数据流编写了一个反序列化程序,该数据流太大,无法实际加载到内存中-使用XmlReader和smart stream seeking(不是所有需要反序列化的数据)。我可以验证这是否有效,尽管使用Environment.NewLine比使用Environment.NewLine更好。那是我唯一的修改。非常感谢。我确实说过这是一个快速而肮脏的例子!:-)