【发布时间】:2019-02-12 11:58:00
【问题描述】:
我有一个案例,Web API 调用返回一个非常大的字符串响应。我拨打电话如下:
var multipartContent = new MultipartFormDataContent();
multipartContent.Add(new ByteArrayContent(blobStream.CopyToBytes()),
"upload", Path.GetFileName(fileName));
var response = await _httpClient.PostAsync("api/v1/textResponse", multipartContent);
int responeLength = response.Content.Headers.ContentLength.HasValue ?
(int)response.Content.Headers.ContentLength.Value : -1;
response.EnsureSuccessStatusCode();
我只需要处理响应中的前 1Mb 数据,因此如果响应小于 1Mb,我将读取所有数据,但如果更多,我将硬停止读取 1Mb。
我正在寻找最有效的阅读方式。我试过这段代码:
// section above...
response.EnsureSuccessStatusCode();
string contentText = null;
if (responeLength < maxAllowedLimit) // 1Mb
{
// less then limit - read all as string.
contentText = await response.Content.ReadAsStringAsync();
}
else {
var contentStream = await response.Content.ReadAsStreamAsync();
using (var stream = new MemoryStream())
{
byte[] buffer = new byte[5120]; // read in chunks of 5KB
int bytesRead;
while((bytesRead = contentStream.Read(buffer, 0, buffer.Length)) > 0)
{
stream.Write(buffer, 0, bytesRead);
}
contentText = stream.ConvertToString();
}
}
这是最有效的方法吗?如何限制阅读量(其他)。我试过这段代码,它总是返回一个空字符串。还有:
ReadAsStringAsync()
ReadAsByteArrayAsync()
ReadAsStreamAsync()
LoadIntoBufferAsync(int size)
这些方法是否更有效?
提前感谢您的任何指点!
【问题讨论】:
-
不确定您的
ConvertToString方法是如何实现的,但您可能需要先将MemoryStream 的Position设置回0 -
另外,看看
Stream.CopyTo- 不需要自己实现。 -
请注意,您不能只获取 UTF-8 字节流,然后在一定数量的字节后硬停止。您很可能最终处于代码点的中间,这将产生无效的字符串。您可以使用 StreamReader,也可以致电
Encoding.GetDecoder() -
我厌倦了这个@canton7 - ``` var contentStream = await response.Content.ReadAsByteArrayAsync(); var text = Encoding.UTF8.GetString(contentStream, 0, _settings.TextSizeUpperLimitBytes);``` 你是这个意思吗?似乎运作良好!这是获取部分流的更有效方式吗?
-
@RobMcCabe 我不建议以任何方式、形状或形式这样做。我说你必须使用
StreamReader,或Encoding.GetEncoder()。第一个适用于流。第二个适用于字节数组,但您可以逐位输入字节。
标签: c# stream memorystream