var incomingStream = ...
var outgoingStream = ...
await incomingStream.CopyToAsync(outgoingStream);
以上代码非常简单,它将传入的流复制到出站流中。这两个流都是通过互联网进行分块传输。
现在,假设我想使用像 Func<Stream, Stream, Task>
这样的东西来转换流,我该如何在不读取所有数据的情况下实现呢?
当然,我可以直接这样做:
var ms = new MemoryStream();
incomingStream.CopyTo(ms);
--- do transform of streams and seek
ms.CopyTo(outgoingStream)
但是那将会把整个东西读入内存,是否有任何内置内容可以让我从传入流中读取并写入新流,而不是缓冲所有数据,而是仅保留一个小的内部流以用于缓冲数据,并且在再次从传入流中获取数据之前,它不会读取。
我想做的是:
protected async Task XmlToJsonStream(Stream instream, Stream outStream)
{
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.IgnoreWhitespace = false;
var reader = XmlReader.Create(instream, readerSettings);
var jsonWriter = new JsonTextWriter(new StreamWriter(outStream));
jsonWriter.WriteStartObject();
while (await reader.ReadAsync())
{
jsonWriter.writeReader(reader);
}
jsonWriter.WriteEndObject();
jsonWriter.Flush();
}
protected async Task XmlFilterStream(Stream instream, Stream outStream)
{
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.IgnoreWhitespace = false;
var reader = XmlReader.Create(instream, readerSettings);
var writer = XmlWriter.Create(outStream, new XmlWriterSettings { Async = true, CloseOutput = false })
while (reader.Read())
{
writer.writeReader(reader);
}
}
但我不知道如何连接它。
var incomingStream = ...
var outgoingStream = ...
var temp=...
XmlFilterStream(incomingStream,temp);
XmlToJsonStream(temp,outgoingstream);
因为如果我使用MemoryStream作为临时存储,那么在结束时它不会将所有内容都存储在流中。我正在寻找一个在读取完数据后可以丢弃数据的流。
以上所有内容仅是示例代码,当然缺少一些处理和查找,但我希望我成功地说明了我的意图。根据设置能够在复制流、进行XML过滤和可选转换为JSON之间进行插拔。
FileStream
)与GZipStream
包装起来,以便每次 SqlClient 流式传输启动ReadAsync
时,我的包装器流都会首先从底层流读取数据,压缩数据,然后返回压缩后的字节到 SqlClient 流式传输中。 - Terry