使用XmlWriter流式写入大型XML文件需配置XmlWriterSettings:Indent设为false、UTF8无BOM、CloseOutput=true、NewLineHandling.None,并直接绑定FileStream,避免内存泄漏;超长内容分块写入并定期Flush。

使用 XmlWriter 流式写入大型 XML 文件,关键在于正确配置 XmlWriterSettings 并避免内存堆积。它不加载整个文档到内存,而是边生成边写入磁盘,适合 GB 级数据。
设置 XmlWriterSettings 提升性能与兼容性
默认设置可能影响写入速度或生成不符合预期的格式。重点配置以下几项:
-
Indent = true:仅在调试或人工阅读时开启;生产环境写大文件建议设为
false,避免额外字符串拼接开销 - Encoding = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false):禁用 BOM,防止某些解析器误判编码;同时显式指定 UTF-8 避免平台默认编码干扰
-
CloseOutput = true:确保写入完成后自动关闭底层
FileStream(若传入的是流) - NewLineHandling = NewLineHandling.None:禁用自动换行处理,减少空白符生成,提升吞吐量
用 FileStream + XmlWriter 避免内存泄漏
不要用 StringWriter 或 MemoryStream 接收大量内容——这会把整个 XML 加载进内存。应直接绑定文件流:
var settings = new XmlWriterSettings
{
Encoding = new UTF8Encoding(false),
Indent = false,
CloseOutput = true,
NewLineHandling = NewLineHandling.None
};
using var fs = new FileStream("output.xml", FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true);
using var writer = XmlWriter.Create(fs, settings);
writer.WriteStartDocument();
writer.WriteStartElement("Root");
// ... 循环写入数百万条 - ...
writer.WriteEndElement();
writer.WriteEndDocument();
注意:缓冲区大小(如示例中 4096)可根据 I/O 特性微调;启用 useAsync: true 对高吞吐场景有帮助(需配合 await using 和异步方法)。
分块写入 + 及时刷新应对超长数据
即使流式写入,若单次调用 WriteElementString 或 WriteRaw 传入超大字符串(如嵌入 Base64 图片),仍可能触发临时内存分配。稳妥做法是:
- 对超长文本内容(>85 KB),拆分为多次
WriteString调用 - 在大批量节点写入后(如每 10,000 条),调用
writer.Flush()确保内核缓冲区落盘(尤其在长时间运行任务中防意外中断丢数据) - 避免在循环内反复创建
XElement或XmlDocument——它们是 DOM 模式,与流式目标相悖
处理特殊字符与命名空间的注意事项
XmlWriter 默认会自动转义 , &, ", ',无需手动处理。但要注意:
- 若需写入 CDATA 块(如含大量未转义 HTML),用
writer.WriteCData("..."),不要拼接字符串 - 声明命名空间时,用
WriteStartElement("prefix", "localName", "namespaceUri"),而非手动写xmlns:...属性 - 不支持直接写注释或处理指令以外的“混合内容”,如需
外再嵌套其他结构,请确保逻辑上符合 XML 层级规则










