是.Disposing StreamWriter关闭底层流?

时间:2009-07-27 11:40:15

标签: c# .net

StreamWriter.Close()表示它还会关闭StreamWriter的基础流。那么StreamWriter.Dispose呢? Dispose是否也处置和/或关闭基础流

6 个答案:

答案 0 :(得分:49)

StreamWriter.Close()只是在引擎盖下调用StreamWriter.Dispose(),所以它们完全相同。 StreamWriter.Dispose()会关闭基础流。

Reflector是您这样的问题的朋友:)

答案 1 :(得分:15)

有些人会说,只是不要处理流,这是一个非常糟糕的主意,因为一旦编写器超出范围,GarbageCollection可以随时拾取并放弃它,从而关闭Handle到流,但创建一个可以轻松覆盖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);
    }
}

如果查看Reflector / ILSpy,你会发现基本流的关闭实际上是在Dispose(true)中完成的,当调用close时它只调用Dispose调用Dispose(True),从代码那里应该没有其他副作用,所以上面的课程效果很好。

你可能想要添加所有的构造函数,为了简单起见,我刚刚添加了2。

答案 2 :(得分:13)

来自StreamWriter.Close()

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

来自TextWriter.Dispose()(StreamWriter继承)

public void Dispose()
{
    this.Dispose(true);
    GC.SuppressFinalize(this);
}
因此,它们完全相同。

答案 3 :(得分:6)

Close和Dispose是StreamWriter的同义词。

答案 4 :(得分:2)

引用Cwalina和Abrams关于处置模式的框架设计指南

  

CONSIDER 除了Close()之外,还提供方法Dispose(),如果close是该区域的标准术语。

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

答案 5 :(得分:1)

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

struct lambda_caller
{
    boost::optional<lambda> _lambda;

    ~lambda_caller()
    {
        if (_lambda) {
            (*_lambda)();
            _lambda = boost::none;
        }
    }

    void release() {
        _lambda = boost::none;
    }
};

这里是解决方案,你必须将Dispose延迟到不再需要底层MemoryStream的地方了:

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

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

我只是喜欢分享这个。