Я пытаюсь оптимизировать отправку больших двоичных данных через HTTP . На данный момент, чтобы отправить его в сжатом виде, мне нужно скопировать весь поток в память:
internal async Task<HttpResponseMessage> PostDataAsync(Stream data, CancellationToken token)
{
using var postMessage = new HttpRequestMessage(HttpMethod.Post, MakeUri());
AddDefaultHttpHeaders(postMessage.Headers);
using var compressedStream = new MemoryStream();
using (var gzipStream = new GZipStream(compressedStream, CompressionLevel.Fastest, true))
await data.CopyToAsync(gzipStream).ConfigureAwait(false);
postMessage.Content = new ByteArrayContent(compressedStream.ToArray());
postMessage.Content.Headers.Add("Content-Encoding", "gzip");
postMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
var response = await httpClient.SendAsync(postMessage, HttpCompletionOption.ResponseHeadersRead, token).ConfigureAwait(false);
return await HandleError(response, sql).ConfigureAwait(false);
}
Однако я считаю, что это менее эффективно, поскольку данные по существу находятся в памяти 4 раза: как оригинальные копировать, как сериализованную копию, как сжатый поток GZip, а затем как ByteArray в конце.
Есть ли способ отправить сжатый поток, не копируя его сначала в MemoryStream
/ byte[]
? Похоже, GZipStream поддерживает только распаковку на лету и не сжатие (CanRead == false
в режиме сжатия)