Решением было реализовать абстрактный класс HttpContent, который будет предоставлять доступ к потоку вывода тела http. Важно отметить, что DeflaterOutputStream закроет свой выходной поток при удалении, мы этого не хотим, поэтому необходимо установить IsStreamOwner
в false.
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
public class ZlibContent : HttpContent
{
private readonly Stream _source;
public ZlibContent(Stream _source)
{
_source = source;
}
protected override async Task SerializeToStreamAsync(Stream destinationStream, TransportContext context)
{
using (var zlibStream = new DeflaterOutputStream(destinationStream) { IsStreamOwner = false })
{
await _source.CopyAsync(zlibStream, this.progress);
}
}
protected override bool TryComputeLength(out long length)
{
length = 0;
return false;
}
}
Поэтому используйте его следующим образом:
using (var fileStream = /* open file stream */)
using (var content = new ZlibContent(fileStream))
{
await httpClient.PostAsync("url", content);
}
Таким образом, ключевым моментом является то, что когда сжатый поток (DeflaterOutputStream) находится в «середине», он не копирует из , а копирует в его. .