IEnumerable 作为流发出?

IEnumerable emit as stream?

有没有办法获取 IEnumerable<T> 并将其作为类似这样的可读流发出?

private void DoTheThing(IEnumerable<Foo> foos)
{
    using (var myStream = foos.EmitAsStream(f =>
    {
        var line = JsonConvert.SerializeObject(f);
        return line;
    }))
    using(var streamReader = new StreamReader(myStream))
    {
        while (!streamReader.EndOfStream)
        {
            var line = streamReader.ReadLine();
            Console.WriteLine(line);
        }
    }
}

显然,这有一些问题,例如它似乎暗示 StreamWriter 指定了 none,但想法是流 reader 只会产生通过引擎盖下的 IEnumerable 枚举,应用转换委托,并在不在内存中创建任何新的、可能很大的对象的情况下提取结果。

我在内存中有一些非常大的可枚举对象,我需要将它们推送到接受流的外部位置(如 Amazon S3)。我真的负担不起用集合构建 MemoryStream 并发送它;我可以假脱机到磁盘并从磁盘读取,但如果可以的话我不想这样做,因为这似乎是一个额外的步骤。

这可能吗?如果可以,实用吗?

如果我理解你的问题,你可以使用 TakeWhile 来实现。

类似于:

while(..end ..) 
{
   var enumeration = foos.TakeWhile(..line bounds..);
   var stream = StreamFromEnum(enumeration ); //custom implementation
   // stream --> S3
}

我假设您对 "line" 有一些自定义定义,这可能是来自流的某种 stride/slice 数据。

A lazily-evaluated stream wrapper for IEnumerableIEnumerable<T> -> Stream 转换的一种可能实现。

EnumerableToStream 软件包将完全满足您的要求:

using EnumerableToStream;

using (var myStream = foos.Select(f =>
{
    var line = JsonConvert.SerializeObject(f);
    return line;
}).ToStream())

ToStream() 方法是最神奇的方法。如果您对实现细节感兴趣,请查看 source code.