我考虑在我们的应用程序中使用System.IO.Pipelines替换基于Stream的IO,以避免不必要的内存分配(首先考虑RecyclableMemoryStream,但似乎已经停产了)。但是在某些地方,由于外部库施加的接口,我仍然必须使用Stream。因此,我的PipeWriter需要将其数据包装在Stream中。
我在这个主题上没有找到太多内容,但是找到了在另一个问题的答案中使用装饰器模式(C# Stream Pipe (Stream Spy))的建议。我不确定将管道隐藏在Stream包装器后面是否是正确的选择,但找不到其他可以将数据通过管道传输到流的内容。我想念什么吗?
更新。这是一个使用SSH.NET开源库将文件上传到FTP服务器(https://gist.github.com/DavidDeSloovere/96f3a827b54f20d52bcfda4fe7a16a0b)的示例:
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.my.example"
minSdkVersion 21
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
targetSdkVersion 27
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
productFlavors {
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
implementation 'junit:junit:4.12'
implementation 'com.android.support.test.espresso:espresso-core:3.0.2'
androidTestImplementation 'com.android.support.test:rules:1.0.2'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
implementation 'postgresql:postgresql:9.0-801.jdbc4'
implementation files('libs/numbers-lib.jar')
}
请注意,我们打开FileStream读取文件,然后将Stream引用传递给SftpClient。我可以在此处使用System.IO.Pipelines减少内存分配吗?我仍然需要为SftpClient提供一个Stream。
答案 0 :(得分:6)
免责声明:我不是专家,只是拼凑起来...
答案(截至2019年1月)似乎是:对此没有官方支持。
System.IO.Pipelines主要是为networking use cases创建的。实际上,2.1中发布的管道代码具有no support for any endpoints:
在这里,我们需要一些警告和免责声明:.NET Core 2.1中发布的管道不包含任何端点实现。
通用流适配器有一个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
更新:我可以制作基于管道的文件阅读器。您可以在这里阅读所有内容:https://github.com/atruskie/Pipelines.File.Unofficial
从性能的角度来看,基本上,使用Nerdbank.Streams这样的管道流适配器是一个不错的选择!
答案 1 :(得分:2)
现在似乎是利用 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));
}