使用MemoryStream写出XML

我注意到有两种不同的方法可以将数据写入XML文件(为简洁起见,省略了error handling)。

第一种方法是构建XML文档,然后将XML保存到文件中:

using (XmlWriter writer = XmlWriter.Create(fileName)) { writer.WriteStartDocument(true); writer.WriteStartElement("parentelement"); writer.WriteEndElement(); writer.WriteEndDocument(); } 

第二种方法是创建MemoryStream,然后将MemoryStream保存到文件中:

 XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; MemoryStream ms = new MemoryStream(); using (XmlWriter writer = XmlWriter.Create(ms, settings)) { writer.WriteStartDocument(true); writer.WriteStartElement("parentelement"); writer.WriteEndElement(); writer.WriteEndDocument(); } using (FileStream fs = File.Open(fileName, FileMode.Create, FileAccess.Write)) { ms.WriteTo(fs); ms.Dispose(); } 

我猜测使用MemoryStream的逻辑是确保在尝试保存文件之前可以构建XML文件。 在将条目添加到XML文件中时,MemoryStream方法是否会提供Atomic写入事件和/或防止写入问题?

任何人都可以解释这是否真的是必要的,或者只是一种过度的方法来为我的项目添加不必要的代码行?

在这种情况下, MemoryStream版本是浪费的。 如果要执行Stream的工作,但不想要实际文件,则MemoryStream非常有用。 如果您正在编写文件,则只需写入该文件即可。 这避免了缓冲内存中所有数据的需要。

确实,内存流方法对于简单操作来说是浪费,但对于将xml保存为加密文件,压缩文件等情况非常有用。

这太过分了,浪费了。

这两个关键方法是基于

  1. 直到最后,您才知道文档的完整结构。
  2. 当您“创建”文档的各个部分时,您知道它们是文档这一部分的最终forms。

第一个需要创建文档的内存模型(DOM是模型的设计)。 一旦你完成它,只需直接写入文件流就可以了。

第二个允许您节省大量内存和复杂性,并简单地使用XmlWriter ,它可以直接指向结束流(在本例中是文件流)。

在任何阶段都不需要使用MemoryStream

如果你(由于某种原因)想要确保XmlWriter成功(即,否则文件可能被截断,但在大多数情况下这将是由于 – 如上所述 – 没有关闭标签)你可以使用临时文件流,fx类似的东西对此:

 public class TempFileStream : FileStream { public TempFileStream(Action onClose) : base(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.ReadWrite) { this.CloseDelegate = onClose; } protected Action CloseDelegate { get; set; } public override void Close() { base.Close(); if (File.Exists(this.Name)) { this.CloseDelegate(this.Name); } } } 

用过的像:

 XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; using (TempFileStream tfs = new TempFileStream(f => File.Move(f, filename)) using (XmlWriter writer = XmlWriter.Create(tfs, settings)) { writer.WriteStartDocument(true); writer.WriteStartElement("parentelement"); writer.WriteEndElement(); writer.WriteEndDocument(); } 

这不会占用大量内存(当然,当生成的XML很大时,它只会使/更有意义)

我认为如果在Web应用程序或Web服务中创建文档,使用内存流会很有用。 文件位置可能与可能正在运行可能导致无效结果的相同处理的另一个进程冲突。 在存储器流中,应该分离处理。

您不必使用MemoryStream来使用XmlWriter。 XmlWriter可以直接写入文件; 您可以使用XmlWriter.Create方法的另一个重载,该方法将文件名作为参数,或者不是写入MemoryStream,您也可以写入XmlTextWriter或FileStream。

所以,你的第二个代码片段可以写成:

 using( FileStream fs = ... ) { XmlWriter writer = XmlWriter.Create (fs); } 

AFAIK,XmlWriter不会保护您免于创建非格式良好的Xml。