C# 使用 MemoryStream 写出到 XML
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/486843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using MemoryStream to write out to XML
提问by Dscoduc
I have noticed two different approaches to writing out data to an XML file (error handling omitted for brevity).
我注意到将数据写入 XML 文件的两种不同方法(为简洁起见省略了错误处理)。
The first method has you build the XML document and then simply save the XML to a file:
第一种方法让您构建 XML 文档,然后简单地将 XML 保存到文件中:
using (XmlWriter writer = XmlWriter.Create(fileName))
{
writer.WriteStartDocument(true);
writer.WriteStartElement("parentelement");
writer.WriteEndElement();
writer.WriteEndDocument();
}
The second method has you create a MemoryStream, and then save the MemoryStream to a file:
第二种方法让您创建一个 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();
}
I'm guessing the logic for using a MemoryStream is to ensure the XML file can be built before trying to save the file. Would the the MemoryStream method provide for an Atomic write event and/or protect against write issues while you are adding entries into the XML file?
我猜测使用 MemoryStream 的逻辑是确保在尝试保存文件之前可以构建 XML 文件。当您将条目添加到 XML 文件时,MemoryStream 方法是否会提供原子写入事件和/或防止写入问题?
Can anyone explain if this is actually necessary or just an overkill way to add unnecessary lines of code to my project?
任何人都可以解释这是否真的有必要,还是只是向我的项目添加不必要的代码行的一种矫枉过正的方式?
采纳答案by Marc Gravell
The MemoryStream
version is wasteful on this occasion. MemoryStream
is useful if you want to perform Stream
-like work, but don't want an actual file. If you arewriting a file, then just write to the file. This avoids the need to buffer all the data in memory.
该MemoryStream
版本是在这个场合浪费。MemoryStream
如果您想执行Stream
类似的工作,但不想要实际文件,则很有用。如果您正在写入文件,则只需写入文件即可。这避免了需要在内存中缓冲所有数据。
回答by Frederik Gheysels
You do not have to use a MemoryStream to use the XmlWriter. The XmlWriter can directly write to a file; you can use another overload of the XmlWriter.Create method, which takes a filename as an argument, or instead of writing to a MemoryStream, you could also write to an XmlTextWriter or a FileStream.
您不必使用 MemoryStream 来使用 XmlWriter。XmlWriter 可以直接写入文件;您可以使用 XmlWriter.Create 方法的另一个重载,该方法将文件名作为参数,或者除了写入 MemoryStream 之外,还可以写入 XmlTextWriter 或 FileStream。
So, you 2nd codesnippet could be written as:
所以,你的第二个代码片段可以写成:
using( FileStream fs = ... )
{
XmlWriter writer = XmlWriter.Create (fs);
}
AFAIK, the XmlWriter will not protect you from creating a non-wellformed Xml.
AFAIK,XmlWriter 不会保护您创建格式不正确的 Xml。
回答by ShuggyCoUk
This is overkill and a waste.
这是矫枉过正和浪费。
The two key approaches are based on
两种主要方法基于
- You do not know the full structure of the document until the end.
- As you 'create' the parts of the document you know that they are the final form of this part of the document.
- 直到最后,您才知道文档的完整结构。
- 当您“创建”文档的各个部分时,您知道它们是文档这部分的最终形式。
the first requires the creation of an in memory model of the document (for which the DOM is model is designed). Once you're finished with it simply writing directly to the file stream is fine.
第一个需要创建文档的内存模型(DOM 是为其设计的模型)。完成后,只需直接写入文件流就可以了。
The second allows you to save considerable memory and complexity and simply use XmlWriterwhich can point directly to the end stream (in this case a file stream).
第二个允许您节省大量内存和复杂性,只需使用可以直接指向结束流(在本例中为文件流)的XmlWriter。
At no stage is it necessary to use a MemoryStream
在任何阶段都不需要使用 MemoryStream
回答by veggerby
If you (for some reason) want to ensure the XmlWriter succeedes (i.e. otherwise the file might be truncated, but in most cases this will be due to - as mentioned - not closing tags) you can use a temporary file stream, fx something similar to this:
如果您(出于某种原因)想要确保 XmlWriter 成功(即,否则文件可能会被截断,但在大多数情况下,这将是由于 - 如上所述 - 未关闭标签)您可以使用临时文件流,fx 类似的东西对此:
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);
}
}
}
The used like:
使用的像:
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();
}
This won't consume a lot of memory (of course it only makes/makes more sense when the resulting XML is large)
这不会消耗大量内存(当然,只有在生成的 XML 很大时才会/更有意义)
回答by Barak C
It is true that the memory stream approach is wasteful for simple operations but it is very useful for cases such as saving the xml as encrypted file, as compressed file etc.
内存流方式对于简单的操作确实是浪费,但是对于将xml保存为加密文件、压缩文件等情况非常有用。
回答by Rich
I think that using a memory stream would be useful if creating the document in a web app or web service. The file location may conflict with another process that could be running the same processing which might cause invalid results. In a memory stream the processing should be segregated.
我认为如果在 Web 应用程序或 Web 服务中创建文档,使用内存流会很有用。文件位置可能与另一个可能正在运行相同处理的进程冲突,这可能会导致无效结果。在内存流中,处理应该是分开的。