2009-07-27 44 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; 
    } 

看着這些例子,我不明白爲什麼關閉底層流是一項功能。

我只是喜歡分享這個。