C#/ .NET的惰性流

时间:2009-11-10 21:39:51

标签: c# .net stream lazy-evaluation

有没有人知道.net中的惰性流实现? IOW,我想要创建一个这样的方法:

public Stream MyMethod() {
    return new LazyStream(...whatever parameters..., delegate() {
        ... some callback code.
    });
}

当我的其他代码调用MyMethod()返回检索流时,在实际尝试从流中读取之前,它实际上不会执行任何工作。通常的方法是让MyMethod将stream参数作为参数,但在我的情况下这不起作用(我想将返回的流提供给MVC FileStreamResult)。

为了进一步解释,我正在寻找的是创建一系列分层转换,所以

数据库结果集=(转换为)=>字节流=(链接到)=> GZipStream =(传递给)=> FileStreamResult构造函数。

结果集可能很大(GB),所以我不想将结果缓存在MemoryStream中,我可以将其传递给GZipStream构造函数。相反,我想从结果集中获取GZipStream请求数据。

3 个答案:

答案 0 :(得分:4)

大多数流实现本质上都是惰性流。通常,任何流都不会从其源中读取信息,直到流的用户请求它(除了一些额外的“过度读取”以允许缓冲发生,这使得流使用更快)。

如果你需要一个完全懒惰的流实现,那么通过覆盖Read来打开底层资源然后在使用它时读取它,直到必要时才能做一个没有读取的Stream实现是相当容易的。只需覆盖Read,CanRead,CanWrite和CanSeek。

答案 1 :(得分:0)

在Stream类中,您必须实现System.IO.Stream的几个方法,包括Read方法。

您在此方法中所做的工作取决于您。如果您选择调用委托 - 这也取决于您,当然您可以将此委托作为构造函数的参数之一传递。至少这是我会这样做的。

不幸的是,它需要的不仅仅是实现读取方法,而且您的委托将不会涵盖其他必需的方法

答案 2 :(得分:-1)

此答案(https://stackoverflow.com/a/22048857/1037948)链接到this article,了解如何编写自己的流类。

引用答案:

  

生产者将数据写入流并且消费者读取数据。中间有一个缓冲区,以便制作人可以提前写'#34;一点点。您可以定义缓冲区的大小。

引用原始来源:

  

您可以将ProducerConsumerStream视为具有Stream接口的队列。在内部,它被实现为循环缓冲区。两个索引跟踪缓冲区内的插入和删除点。字节在Head索引处写入,并从尾部索引中删除。

     

如果Head回绕到Tail,那么缓冲区已满,生产者必须等待一些字节才能继续写入。类似地,如果Tail赶上Head,消费者必须等待字节写入才能继续。

本文继续描述一些奇怪的情况,当指针环绕时,带有完整的代码样本。