谁拥有.NET中的换行流(例如TextWriter)

本文关键字:例如 TextWriter 换行 拥有 NET | 更新日期: 2023-09-27 17:59:01

我最近遇到一个错误"ObjectDisposedException:无法访问关闭的流"

[ObjectDisposedException: Cannot access a closed Stream.]
    System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) +10184402
    System.Security.Cryptography.CryptoStream.FlushFinalBlock() +114
    System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing) +48

当使用以下格式的代码时:

using (var stream = new MemoryStream())
{
    using (var hashStream = new CryptoStream(stream,
                                    new SHA256Managed(), CryptoStreamMode.Write))
    using (var writer = new TextWriter(hashStream))
    {
        writer.Write("something");
    }
    // ^-- Exception occurs on hashStream Dispose
    //     While naively I assumed that TextWriter.Dispose wouldn't touch the
    //     underlying stream(s).
    return stream.ToArray();
}

因此,之所以会导致异常,是因为TextWriter的Dispose处理了被包装的流(hashStream)。我的问题是:

  1. 此约定是否应用于.NET中的所有流(带有默认构造函数/参数)?

    有没有正典在讨论这种资源使用模式?例如,可以假设CryptoStream会关闭MemoryStream吗?我知道答案,还有其他具体的问题,但如果有设计指南的话,我希望它能得到解决。

  2. 这种行为记录在哪里?

    我找不到TextWriter(stream)CryptoStream构造函数中讨论的"所有权"——当然我只是看错了位置。(更新:很明显,我阅读失败了,正如它86所指出的,这个记录在TextWriter构造函数文档中。)

  3. 编写此类代码的通用方法是什么?

    也就是说,底层流需要被读取(在所有操作结束时,因此仍然打开),而所有嵌套流应该完全关闭/刷新-一个简单的CryptoStream。例如,刷新是不够的。

谁拥有.NET中的换行流(例如TextWriter)

StreamWriter()文档中特别提到了这一点。

当调用StreamWriter.Dispose时,StreamWriter对象对提供的Stream对象调用Dispose()。

在阅读了using语句C#规范并查看了一些已实现的流(内存、文件等)后,我发现默认行为是在调用Dispose()时处理底层流。在某些流中,您可以明确表示不想处理底层流,如DeflateStream:

public DeflateStream(Stream stream, CompressionLevel compressionLevel, bool leaveOpen)

leaveOpen Type:System.Boolean true以保持流对象打开在处理所述DeflateStream对象之后;否则为false。

当然,您可以通过不使用using语句来解决处理问题,或者实现一个WrapperStream类来包装您的流,而不处理底层流。

相关文章: