C# .Disposing a StreamWriter 会关闭底层流吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1187700/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 10:20:50  来源:igfitidea点击:

Does .Disposing a StreamWriter close the underlying stream?

c#.net

提问by nos

The StreamWriter.Close() says it also closes the underlying stream of the StreamWriter. What about StreamWriter.Dispose ? Does Dispose also dispose and/or close the underlying stream

StreamWriter.Close() 表示它还关闭了 StreamWriter 的底层流。StreamWriter.Dispose 呢?Dispose 是否也处理和/或关闭底层流

采纳答案by Rob Levine

StreamWriter.Close() just calls StreamWriter.Dispose() under the bonnet, so they do exactly the same thing. StreamWriter.Dispose() does close the underlying stream.

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

Reflectoris your friend for questions like this :)

Reflector是您解决此类问题的朋友 :)

回答by Joel Coehoorn

Close and Dispose are synonymous for StreamWriter.

Close 和 Dispose 是 StreamWriter 的同义词。

回答by ShuggyCoUk

From StreamWriter.Close()

从 StreamWriter.Close()

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

From TextWriter.Dispose() (which StreamWriter inherits)

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

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

They are thus, identical.

因此,它们是相同的。

回答by Martin Liversage

To quote from Framework Design Guidelinesby Cwalina and Abrams in the section about the dispose pattern:

引用Cwalina 和 Abrams 在有关处置模式的部分中的框架设计指南

CONSIDERproviding method Close(), in addition to the Dispose(), if close is standard terminology in the area.

考虑提供方法Close(),除了Dispose(), if close 是该地区的标准术语。

Apparently Microsoft follow their own guidelines, and assuming this is almost always a safe bet for the .NET base class library.

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

回答by Aaron Murgatroyd

Some people will say, just dont dispose the stream, this is a really bad idea, because once the streamwriter goes out of scope GarbageCollection can pick it up anytime and dipose it, thus closing the Handle to the stream, but creating a descendant class which overrides this behaviour of StreamWriter is easy, heres the code:

有些人会说,只是不要处理流,这是一个非常糟糕的主意,因为一旦流写入器超出范围,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);
    }
}

If you look in Reflector / ILSpy you will find that the closing of the base stream is actually done in Dispose(true), and when close is called it just calls Dispose which calls Dispose(True), from the code there should be no other side effects, so the class above works nicely.

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

You might want to add all the constructors though, i have just added 2 here for simplicity.

不过,您可能想要添加所有构造函数,为了简单起见,我刚刚在此处添加了 2 个。

回答by Roland

The answer is simple, and provided above: yes, disposing a stream closes any underlying stream. Here is an example:

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

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

and here the solution, where you have to delay Dispose to where the underlying MemoryStream is not needed anymore:

这里是解决方案,您必须将 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;
    }

Looking at these examples, I do not understand why closing the underlying stream is a feature.

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

I just liked to share this.

我只是喜欢分享这个。