5

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

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

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

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

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

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

4

3 回答 3

5

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

如果您需要一个完全惰性的流实现,那么通过重写Read打开底层资源然后在使用时从它读取来创建一个在必要之前不读取的 Stream 实现是相当容易的。只需覆盖 Read、CanRead、CanWrite 和 CanSeek。

于 2009-11-10T21:49:11.693 回答
0

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

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

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

于 2009-11-10T21:49:40.340 回答
-1

这个答案(https://stackoverflow.com/a/22048857/1037948)链接到这篇关于如何编写自己的流类的文章。

引用答案:

生产者将数据写入流,消费者读取。中间有一个缓冲区,以便生产者可以“提前写”一点。您可以定义缓冲区的大小。

引用原始来源:

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

如果 Head 回绕到 Tail,则缓冲区已满,生产者必须等待读取一些字节才能继续写入。同样,如果 Tail 赶上 Head,消费者必须等待字节被写入才能继续。

本文继续描述了指针环绕时的一些奇怪情况,并提供了完整的代码示例。

于 2015-05-28T17:43:26.530 回答