2009-07-27 42 views

回答

42

StreamWriter.Close()只是在引擎盖下调用StreamWriter.Dispose(),所以它们完全一样。 StreamWriter.Dispose()会关闭底层的流。

Reflector是你的朋友对这样的问题:)

+1

从技术上讲,它称之为Dispose(布尔)在发动机罩下,尽管 – ShuggyCoUk 2009-07-27 12:27:01

+1

是最小的挑逗。我应该说它“调用处置”,而没有真正指定哪个过载。好点。 – 2009-07-27 13:14:05

6

Close和Dispose是StreamWriter的同义词。

+0

好吧,几乎是同义词。 – 2012-05-16 21:49:54

11

从StreamWriter.Close()

public override void Close() 
{ 
    this.Dispose(true); 
    GC.SuppressFinalize(this); 
} 

从TextWriter.Dispose()(其中StreamWriter的继承)

public void Dispose() 
{ 
    this.Dispose(true); 
    GC.SuppressFinalize(this); 
} 

他们因此是相同的。

2

从由Cwalina和艾布拉姆斯框架设计指南在部分引述有关Dispose模式:

考虑提供方法Close(),除了Dispose(),如果收盘价标准术语的区。

显然,Microsoft遵循自己的指导方针,并假设这对于.NET基类库几乎总是一个安全的选择。

14

有人会说了,只是不处分流,这是一个非常糟糕的主意,因为一旦StreamWriter的超出范围垃圾回收可以随时把它捡起来,并dipose它,从而关闭句柄流,但创建它覆盖的StreamWriter此行为的子类是容易的,继承人的代码:

/// <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); 
    } 
} 

如果你在反射看起来/ ILSpy你会发现,基本流的结束在处置(真)实际完成,当close被调用时它只是调用Dispose来调用Dispose(True),从代码中应该没有其他副作用,所以上面的类很好地工作。

虽然您可能想要添加所有构造函数,但为了简单起见,我在此仅添加了2个。

1

答案很简单,并在上面提供:是的,处理一个流会关闭任何基础流。这里有一个例子:

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; 
    } 

和这里的解决方案,在那里你必须处置推迟到不需要底层的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; 
    } 

看着这些例子,我不明白为什么关闭底层流是一项功能。

我只是喜欢分享这个。