C#: как отправить сжатый поток по HTTP, не копируя его? - PullRequest
0 голосов
/ 06 февраля 2020

Я пытаюсь оптимизировать отправку больших двоичных данных через 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 в режиме сжатия)

...