Я подозреваю, что наиболее эффективный (но все же правильный) способ сделать это, вероятно, что-то вроде этого.Это усложняется тем, что у вас есть ограничение на количество байтов , которые читаются, а не на количество символов , и поэтому мы не можем использовать StreamReader
.Обратите внимание, что мы должны быть осторожны, чтобы не остановить чтение в середине кодовой точки - во многих случаях один символ представлен с использованием нескольких байтов, и остановка на полпути будет ошибкой.
const int bufferSize = 1024;
var bytes = new byte[bufferSize];
var chars = new char[Encoding.UTF8.GetMaxCharCount(bufferSize)];
var decoder = Encoding.UTF8.GetDecoder();
// We don't know how long the result will be in chars, but one byte per char is a
// reasonable first approximation. This will expand as necessary.
var result = new StringBuilder(maxAllowedLimit);
int totalReadBytes = 0;
using (var stream = await response.Content.ReadAsStreamAsync())
{
while (totalReadBytes <= maxAllowedLimit)
{
int readBytes = await stream.ReadAsync(
bytes,
0,
Math.Min(maxAllowedLimit - totalReadBytes, bytes.Length));
// We reached the end of the stream
if (readBytes == 0)
break;
totalReadBytes += readBytes;
int readChars = decoder.GetChars(bytes, 0, readBytes, chars, 0);
result.Append(chars, 0, readChars);
}
}
Обратите внимание, что вы, вероятно, захотите использовать HttpCompletionOption.ResponseHeadersRead
, иначе HttpClient
все равно загрузит все тело.
Если вы счастливы, ограничив число символы , тогда жизнь станет проще:
string result;
using (var reader = new StreamReader(await response.Content.ReadAsStreamAsync()))
{
char[] chars = new char[maxAllowedLimit];
int read = reader.ReadBlock(chars, 0, chars.Length);
result = new string(chars, 0, read);
}