解决方案是实现 HttpContent 抽象类,它可以访问 http 正文的输出流。需要注意的是,DeflaterOutputStream 将在 dispose 时关闭其输出流,我们不希望这样,因此必须设置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);
}
所以关键是当compress-stream(DeflaterOutputStream)在“中间”时,不是从它复制,而是复制到它。