在使用Stream之后离开Stream的社交可接受方式是什么?

时间:2013-08-15 15:31:13

标签: c#

如果您正在设计API,或者甚至在您自己的代码中,并且您的方法接受Stream,那么您的方法是检查位置并将其重置为开头的责任,前提是CanSeek使用之前是true吗?

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

多年来,我假设Stream在位置0进入我的方法时被抓了几次。

使用它后,尽可能重置Stream吗?

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

3 个答案:

答案 0 :(得分:10)

  

如果CanSeek在使用之前是真的,那么你的方法有责任检查位置并将其重置为开头吗?

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

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

使用之后最好的事情是:什么也不做。

答案 1 :(得分:3)

  

如果CanSeek在使用之前是真的,那么你的方法有责任检查位置并将其重置为开头吗?

不,有两个原因:

  • 它并不总是可能的(例如,如果CanSeek为假),所以如果你为某些流而不是为其他流而这样做会很奇怪
  • BCL课程不这样做。例如,StreamReader在处理时关闭基础流,它不会将其恢复到以前的状态。

答案 2 :(得分:0)

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

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

因此,如果应用程序有责任为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的情况下将在仅向前流上成功。