使用流后离开流的社会可接受的方式是什么?

本文关键字:方式 是什么 可接受 社会 离开 | 更新日期: 2023-09-27 18:27:54

如果你正在设计一个API,甚至在你自己的代码中,并且你的方法接受一个Stream,你的方法是否有责任检查位置并将其重置到开头,前提是在使用之前CanSeek true

如果是这样,为什么没有一种方法可以在Stream类本身上执行所有这些操作?

多年来,我有几次被抓住,假设Stream进入我的方法处于位置 0。

使用后尽可能重置Stream是否正确?

或者,Stream是否应该始终复制而不是直接传递?对我来说似乎有点过分。

使用流后离开流的社会可接受的方式是什么?

您的方法是否有责任检查位置并将其重置到开头,前提是 CanSeek 在使用之前为真?

不,在这种情况下,我希望调用代码正确准备流。

通过方法共享流的最常见模式要求指针在最后一次读/写之后完全保留,因此这永远不会出现太多。

但使用它最好的办法是:什么都不做。

您的方法是否有责任检查位置并将其重置到开头,前提是 CanSeek 在使用之前为真?

不,原因有二:

  • 这并不总是可能的(例如,如果CanSeek是假的(,所以如果你对某些流而不是对其他流这样做会很奇怪
  • BCL 类不这样做。例如,StreamReader释放基础流时关闭它,它不会将其还原到以前的状态。

我不想更新这个问题,因为人们已经投票了,但可能不喜欢这部分:)

这非常有趣(谢谢(,并且清楚地显示了设计可重用库样式代码与应用程序代码时思维的差异。

因此,如果应用程序负责为 API 准备Stream(似乎我们都同意(,那么我们可以将有用的逻辑"提升"到应用程序中的扩展方法中。

    /// <summary>
    /// Tries to set the stream to position 0 if required.
    /// </summary>
    /// <returns>
    /// False if the stream is not at position 0 and does not support seek operations.
    /// </returns>
    public static bool TrySetPositionZero(this Stream stream)
    {
        if (stream.Position > 0)
        {
            if (stream.CanSeek)
            {
                stream.Position = 0;
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            return true;
        }
    }

这与简单stream.Position = 0之间的区别在于,它有更多的成功机会,因为它将在已经处于位置 0 的仅转发流上成功。