是否.Disposing StreamWriterclosures基础stream?
StreamWriter.Close()表示它也closures了StreamWriter的基础stream。 什么StreamWriter.Dispose? Dispose是否也处理和/或closures底层stream
StreamWriter.Close()只是在引擎盖下调用StreamWriter.Dispose(),所以它们完全一样。 StreamWriter.Dispose()会closures底层的stream。
reflection器是你的朋友这样的问题:)
有些人会说,只是不处理stream,这是一个非常糟糕的主意,因为一旦Streamwriter超出了范围,GarbageCollection可以随时将其提取出来,然后将其合并,从而closuresHandle到stream,但是创build一个后代类覆盖StreamWriter的这种行为很容易,inheritance人的代码:
/// <summary> /// Encapsulates a stream writer which does not close the underlying stream. /// </summary> public class NoCloseStreamWriter : StreamWriter { /// <summary> /// Creates a new stream writer object. /// </summary> /// <param name="stream">The underlying stream to write to.</param> /// <param name="encoding">The encoding for the stream.</param> public NoCloseStreamWriter(Stream stream, Encoding encoding) : base(stream, encoding) { } /// <summary> /// Creates a new stream writer object using default encoding. /// </summary> /// <param name="stream">The underlying stream to write to.</param> /// <param name="encoding">The encoding for the stream.</param> public NoCloseStreamWriter(Stream stream) : base(stream) { } /// <summary> /// Disposes of the stream writer. /// </summary> /// <param name="disposing">True to dispose managed objects.</param> protected override void Dispose(bool disposeManaged) { // Dispose the stream writer but pass false to the dispose // method to stop it from closing the underlying stream base.Dispose(false); } }
如果您查看Reflector / ILSpy,您会发现基本stream的closures实际上是在Dispose(true)中完成的,并且在调用close时调用Dispose(调用Dispose(True)),从代码中不应该有其他副作用,所以上面的类很好地工作。
你可能想要添加所有的构造函数,但是为了简单起见,我在这里只添加了2个。
从StreamWriter.Close()
public override void Close() { this.Dispose(true); GC.SuppressFinalize(this); }
从TextWriter.Dispose()(StreamWriterinheritance)
public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); }
因此,它们是相同的。
Close和Dispose是StreamWriter的同义词。
引用Cwalina和Abrams在框架devise指南中有关处置模式的部分:
考虑提供方法
Close()
,除了Dispose()
,如果close是标准术语的话。
显然微软遵循自己的指导原则,并假设这对.NET基类库几乎总是一个安全的赌注。
答案很简单,上面提供:是的,处理一个streamclosures任何基础stream。 这里是一个例子:
public static string PrettyPrintXML_bug(XDocument document) { string Result = ""; using (MemoryStream mStream = new MemoryStream()) { using (XmlTextWriter writer = new XmlTextWriter(mStream, Encoding.Unicode)) { writer.Formatting = Formatting.Indented; // <<--- this does the trick // Write the XML into a formatting XmlTextWriter document.WriteTo(writer); // change the memory stream from write to read writer.Flush(); mStream.Flush(); } // <-- <-- <-- <-- <-- <-- <-- <-- <-- <-- this also "closes" mStream mStream.Position = 0;//rewind <-- <-- <-- "cannot Read/Write/Seek" // Read MemoryStream contents into a StreamReader. using (StreamReader sReader = new StreamReader(mStream)) // <-- <-- Exception: Cannot access a closed stream { // Extract the text from the StreamReader. Result = sReader.ReadToEnd(); } } return Result; }
这里的解决scheme,你必须延迟Dispose到底层MemoryStream不再需要的地方:
public static string PrettyPrintXML(XDocument document) { string Result = ""; using (MemoryStream mStream = new MemoryStream()) { using (XmlTextWriter writer = new XmlTextWriter(mStream, Encoding.Unicode)) { writer.Formatting = Formatting.Indented; // <<--- this does the trick // Write the XML into a formatting XmlTextWriter document.WriteTo(writer); // change the memory stream from write to read writer.Flush(); writer.Close(); mStream.Flush(); mStream.Position = 0;//rewind // Read MemoryStream contents into a StreamReader. using (StreamReader sReader = new StreamReader(mStream)) { // Extract the text from the StreamReader. Result = sReader.ReadToEnd(); } }// <-- here the writer may be Disposed } return Result; }
看这些例子,我不明白为什么closures基础stream是一个function。
我只是喜欢分享这个。