有没有人知道.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请求数据。
答案 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,消费者必须等待字节写入才能继续。
本文继续描述一些奇怪的情况,当指针环绕时,带有完整的代码样本。