将System.IO.Pipelines与Stream一起使用



我考虑用System.IO.Pipelines替换应用程序中基于流的IO,以避免不必要的内存分配(考虑了第一个可循环内存流,但它似乎已停止(。但在某些地方,由于外部库强加的接口,我仍然必须使用Stream。因此,我的PipeWriter需要将其数据封装在流中。

我在这个主题上没有发现太多,但在回答另一个问题时,我发现了一个使用decorator模式(C#Stream Pipe(Stream Spy((的建议。我不确定将Pipelines隐藏在Stream包装器后面是否正确,但找不到任何其他可以将数据管道传输到流的东西。我是不是错过了什么?

更新。下面是一个使用SSH.NET开源库将文件上传到FTP服务器的示例(https://gist.github.com/DavidDeSloovere/96f3a827b54f20d52bcfda4fe7a16a0b):

using (var fileStream = new FileStream(uploadfile, FileMode.Open))
{
Console.WriteLine("Uploading {0} ({1:N0} bytes)", uploadfile, fileStream.Length);
client.BufferSize = 4 * 1024; // bypass Payload error large files
client.UploadFile(fileStream, Path.GetFileName(uploadfile));
}

请注意,我们打开FileStream来读取文件,然后将Stream引用传递给SftpClient。我可以在这里使用System.IO.Pipelines来减少内存分配吗?我仍然需要为SftpClient提供一个流。

免责声明:我不是专家,只是拼凑。。。


答案(截至2019年1月(似乎是:没有官方支持。

System.IO.Pipelines主要是为网络用例创建的。事实上,2.1中发布的管道代码不支持任何端点:

这里我们需要一点警告和免责声明:.NET Core 2.1中发布的管道不包括任何端点实现。

有一个针对通用流适配器的API的拟议设计,但这是.NET Core 3.0里程碑的一部分。

甚至似乎对实现基于文件的管道访问(也就是FileStream管道的等价物(有些保留。这尤其令人失望,因为我也希望管道驱动的文件I/O。

我认为您目前最好的选择是在中使用UsePipe()方法https://github.com/AArnott/Nerdbank.Streams


更新:这是我刚刚发现的另一个例子https://github.com/tulis/system-io-pipelines-demo/tree/master/src/SystemIoPipelinesDemo/SystemIoPipelinesDemo


更新:我尝试过制作一个基于管道的文件读取器。你可以在这里阅读有关它的全部内容:https://github.com/atruskie/Pipelines.File.Unofficial

从本质上讲,从性能的角度来看,使用像Nerdbank这样的管道流适配器。Streams是一个很好的方法!

现在似乎是一种利用PipeReader:的AsStream((扩展的方法

using (var fileStream = new FileStream(uploadfile, FileMode.Open))
{
Console.WriteLine("Uploading {0} ({1:N0} bytes)", uploadfile, fileStream.Length);
client.BufferSize = 4 * 1024; // bypass Payload error large files
var pipeReader = PipeReader.Create(fileStream);
client.UploadFile(pipeReader.AsStream(), Path.GetFileName(uploadfile));
}

相关内容

最新更新