将 System.IO.Pipelines 与 Stream 一起使用
Using System.IO.Pipelines together with Stream
我考虑用 System.IO.Pipelines 替换我们应用程序中基于 Stream 的 IO 以避免不必要的内存分配(首先考虑 RecyclableMemoryStream 但它似乎已停产)。但在某些地方,由于外部库强加的接口,我仍然必须使用 Stream。所以我的 PipeWriter 需要将其数据包装在 Stream 中。
我没有找到太多关于这个主题的信息,但在另一个问题的答案中找到了使用装饰器模式 () 的建议。我不确定将管道隐藏在 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 主要是为 networking use cases. In fact, the pipelines code released in 2.1 had no support for any endpoints 创建的:
Here we need a bit of caveat and disclaimer: the pipelines released in .NET Core 2.1 do not include any endpoint implementations.
通用流适配器有一个 proposed design for an API,但它是 .NET Core 3.0 里程碑的一部分。
甚至 seems to be some reticence 实现基于文件的管道访问(又称为 FileStream
管道等效)。这尤其令人失望,因为我也希望管道驱动文件 I/O.
我认为目前最好的选择是使用 https://github.com/AArnott/Nerdbank.Streams
中的 UsePipe()
方法
更新: 这是我刚找到的另一个例子 https://github.com/tulis/system-io-pipelines-demo/tree/master/src/SystemIoPipelinesDemo/SystemIoPipelinesDemo
更新: 我试着制作一个基于管道的文件 reader。您可以在这里阅读所有相关信息: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));
}
我考虑用 System.IO.Pipelines 替换我们应用程序中基于 Stream 的 IO 以避免不必要的内存分配(首先考虑 RecyclableMemoryStream 但它似乎已停产)。但在某些地方,由于外部库强加的接口,我仍然必须使用 Stream。所以我的 PipeWriter 需要将其数据包装在 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 主要是为 networking use cases. In fact, the pipelines code released in 2.1 had no support for any endpoints 创建的:
Here we need a bit of caveat and disclaimer: the pipelines released in .NET Core 2.1 do not include any endpoint implementations.
通用流适配器有一个 proposed design for an API,但它是 .NET Core 3.0 里程碑的一部分。
甚至 seems to be some reticence 实现基于文件的管道访问(又称为 FileStream
管道等效)。这尤其令人失望,因为我也希望管道驱动文件 I/O.
我认为目前最好的选择是使用 https://github.com/AArnott/Nerdbank.Streams
中的UsePipe()
方法
更新: 这是我刚找到的另一个例子 https://github.com/tulis/system-io-pipelines-demo/tree/master/src/SystemIoPipelinesDemo/SystemIoPipelinesDemo
更新: 我试着制作一个基于管道的文件 reader。您可以在这里阅读所有相关信息: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));
}