【问题标题】:Why a BinaryWriter closes the outer Stream on disposal, and how to prevent that? (.NET C#)为什么 BinaryWriter 在处理时关闭外部 Stream,以及如何防止这种情况? (.NET C#)
【发布时间】:2010-11-08 06:15:54
【问题描述】:

我有一种方法可以接收 Stream 以使用 BinaryWriter 对其进行写入。但是当我处理这个 BinaryWriter 时,它也会关闭流。我可以不处理它,以便让我的信息流保持打开状态吗?

【问题讨论】:

    标签: c# .net stream binarywriter


    【解决方案1】:

    从 .NET 4.5 开始,BinaryWriter 类有一个新的构造函数,它接受一个布尔参数来指示是否让流保持打开状态。

    参考:http://msdn.microsoft.com/en-us/library/gg712841.aspx

    public BinaryWriter(
        Stream output,
        Encoding encoding,
        bool leaveOpen
    )
    

    【讨论】:

    • @JaderDias 我知道这是很久以前的事了,但您应该考虑将其标记为答案。
    【解决方案2】:

    BinaryWriter 的情况下,这不是一个直接选项(尽管某些流包装器确实允许您控制它,例如GZipStream 等)。

    Jon 在MiscUtil 中有一个 NonClosingStreamWrapper,它应该可以工作:您将流包装在非关闭包装器中,并将包装器提供给 BinaryWriter。这基本上会通过除Close()Dispose() 之外的所有内容。

    【讨论】:

    • 你不觉得有一点hack吗?您建议通过使用包装器愚弄 BinnaryWriter 来改变其行为(和假设)?
    • 不,与BinaryWriter 相关的根本没有任何改变;它将值写入流并告诉流何时完成。关心扩展您的想法吗?这肯定比不处理 IDisposable 的东西要很多,因为你偷看了实现并决定否决它......
    • 这会改变二进制写入器的预期行为。由于 close 和 dispose 操作的预期行为,binnarywriter 不会费心闪存。通过过滤 close 和 dispose 函数,您只需引入在 Cirtan 情况下很难找到的错误。
    • 当 BinaryWriter 关闭时,它会刷新 自身 并告诉流关闭;使用包装器,它仍然会自行刷新。 stream 没有关闭的区别。
    • 为什么NonClosingStreamWrapper关闭后会抛出InvalidOperationException而不是ObjectDisposedException?
    【解决方案3】:

    只是不要调用 Dispose,而是使用 Flush,它是安全的。

    【讨论】:

    • 今天是安全的。您是否打算在 .NET 的任何版本中使用 Reflector 以确保它继续安全?这不是解决方案。 -1.
    • 它永远是安全的。只是因为作家语义。想想为什么它现在已经处置(提示查看 msdn 上的示例)。另请注意,这不是 .NET 中唯一不正确使用 IDisposable 的地方,例如众所周知的 WCF 通道的 Dispose 问题。
    • 它有一个 dispose ,因为假设它现在拥有流的生命周期。但如果我们不希望这样,那么我认为正确的做法是将两者分开 - 而不是破解我们如何使用作者。作家是一次性的;我们应该处理它。简而言之,我不同意。
    • “对象是一次性的这一事实不需要调用 dispose”——我们再次不同意。 IDisposable 是一个合同;除非你有很好的理由,否则你应该在完成后处理它。其他任何东西都会破坏封装。你不应该知道或关心它需要什么一次性的......它是一次性的:丢弃它。也回复了您的其他评论(在我的帖子上)。
    • 幸运的是,BinaryWriter 不像FileStream 那样在Finalize 中调用Dispose。这种行为意味着BinaryWriter.Dispose 是可选的。
    【解决方案4】:

    受保护的 BinaryWriter.Dispose(bool) 方法是虚拟的,它所做的只是关闭流(您可以在Reflector 中检查它是否为真)。 - 该方法由 Dispose() 方法调用。

    您可以简单地从 BinaryWriter 继承一个类并重写 Dispose(bool) 方法以不执行任何操作,或者一起执行其他操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-15
      • 2013-03-28
      • 1970-01-01
      • 2021-12-30
      • 2023-03-10
      • 1970-01-01
      • 2012-01-04
      • 2011-02-17
      相关资源
      最近更新 更多