使用MemoryStream写出XML

时间:2009-01-28 08:10:25

标签: c# xml memorystream

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

第一种方法是构建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写入事件和/或防止写入问题?

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

6 个答案:

答案 0 :(得分:15)

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

答案 1 :(得分:3)

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

答案 2 :(得分:2)

这太过分了,浪费了。

这两个关键方法基于

  1. 直到最后,您才知道文档的完整结构。
  2. 当您“创建”文档的各个部分时,您知道它们是文档此部分的最终形式。
  3. 第一个需要创建文档的内存模型(DOM是模型的设计)。一旦完成它,只需直接写入文件流即可。

    第二个允许您节省大量内存和复杂性,只需使用XmlWriter即可直接指向结束流(在本例中为文件流)。

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

答案 3 :(得分:1)

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

public class TempFileStream : FileStream
{

    public TempFileStream(Action<string> onClose)
        : base(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.ReadWrite)
    {
        this.CloseDelegate = onClose;
    }

    protected Action<string> 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很大时才会使/更有意义)

答案 4 :(得分:1)

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

答案 5 :(得分:0)

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

所以,你的第二个codenippet可以写成:

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

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