0

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

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

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

4

1 回答 1

1

解决方案是实现 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)在“中间”时,不是它复制,而是复制它。

于 2020-05-08T15:07:42.980 回答