如何使用ICSharpCode.SharpZipLib压缩文件数据并使用HttpClient上传?

How to compress file data with ICSharpCode.SharpZipLib and upload using HttpClient?

我正在使用 ICSharpCode.SharpZipLib 并执行以下操作:读取文件内容、压缩 (zlib),然后使用 HttpClient.PostAsync

上传到服务器

我的常规方法(适用于相应的下载)是创建一个压缩的输出流,然后 Copy/CopyAsync 从输出到 StreamContent。但是,DeflaterOutputStream 不支持读取,所以这行不通。应该如何有效地完成?可能只有我一个人,但答案并不明显。

我知道我可以先将文件压缩到内存中(即 MemoryStream 或字节数组),然后将它们复制到 http 内容,但这是不可接受的

解决方案是实现 HttpContent 抽象 class,这将提供对 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);
}

所以重点是compress-stream(DeflaterOutputStream)在"middle"的时候,不是从复制,而是复制吧。