MemoryStream из HttpContent без копирования

Я пытаюсь использовать System.Net.Http для запросов POST. Я нормально отношусь к тому, что тело ответа HTTP находится в памяти, но для этого нужно получить MemoryStream. Один из способов сделать это - вызвать HttpContent.GetAsByteArrayAsync () и обернуть поверх него MemoryStream, но я думаю, что для этого потребуется скопировать контент в отдельный массив байтов (поскольку он возвращает Task of byte []).

Если тело ответа уже находится в каком-то внутреннем буфере в HttpContent, возможно ли создать MemoryStream поверх этого буфера или каким-то образом вернуть MemoryStream из HttpContent и избежать копирования в отдельный массив байтов?

Существует также HttpContent.GetAsStreamAsync (), но он возвращает обычный Stream, а не MemoryStream. Хотя это, вероятно, уже является экземпляром MemoryStream, я полагаю, это небезопасно или не рекомендуется приводить возвращенный поток в MemoryStream? (поскольку это деталь реализации, которая может измениться).

Есть ли другой способ сделать это, или у меня нет выбора, кроме как сначала скопировать в byte []?

Спасибо.


person Yevgeniy P    schedule 19.03.2020    source источник


Ответы (1)


Если вы сначала вызовете LoadIntoBufferAsync, ReadAsStreamAsync вернет только для чтения MemoryStream:

await req.Content.LoadIntoBufferAsync();
var stream = (MemoryStream) await req.Content.ReadAsStreamAsync();
person weichch    schedule 19.03.2020
comment
Спасибо, это похоже на правильный путь, однако я не смог найти документ, в котором упоминается, что ReadAsStreamAsync будет возвращать MemoryStream только для чтения после вызова LoadIntoBufferAsync. Есть ли по этому поводу какие-либо документы или примеры от Microsoft? - person Yevgeniy P; 19.03.2020
comment
Не думаю, что есть документы. Если вы не доверяете реализации, вы можете использовать ReadAsByteArray() и создать MemoryStream с помощью этого конструктора public MemoryStream (byte[] buffer, bool writable);. Это то, что HttpContent делает внутри компании. И он не будет копировать буфер. - person weichch; 19.03.2020
comment
Есть исходный код между github. com / microsoft / referenceource / blob / master / System / net / - person weichch; 19.03.2020
comment
Спасибо, да, из исходного кода похоже, что он возвращает поток памяти. Похоже, что это лучший способ в данных обстоятельствах, однако не уверен, будет ли он надежным в будущих выпусках. Я предполагаю, чтобы быть уверенным, что могу вызвать ReadAsStreamAsync () и проверить, является ли экземпляр MemoryStream, а если нет, то скопируйте возвращенный поток в новый MemoryStream. Я думаю, что ReadAsByteArrayAsync скопирует буфер (по крайней мере, в исходном коде он вызывает MemoryStream.ToArray (), который делает копию). - person Yevgeniy P; 19.03.2020
comment
У вас может быть модульный тест, охватывающий литой бит. Если вы обновитесь до новой версии, это поведение изменится. Ваш модульный тест не удастся, и вы узнаете. - person weichch; 19.03.2020