将 GZipStream 复制到文件

问题描述 投票:0回答:1

我想将使用 gzip 编码上传到 S3 的文件直接解压缩到文件流。

这是我在解压缩S3流后返回gzip流的方法:

using var stream = await _s3.GetObjectStreamAsync(_processServiceOptions.BucketName, key, null);
using var gzipStream = new GZipStream(stream, CompressionMode.Decompress, true);
await WriteToFileAsync(gzipStream);

我尝试像这样使用它,将其直接复制到文件流,而不是使用另一个流将其加载到内存中...

async Task WriteToFileAsync(Stream data)
{
    using (var fs = File.OpenWrite(path))
    {
        await data.CopyToAsync(fs);
    }
}

但是我越来越

System.IO.InvalidDataException: The archive entry was compressed using an unsupported compression method.

这是为什么?

c# amazon-s3 gzip gzipstream
1个回答
0
投票

对于仍在寻找答案的人(我知道我确实这样做了),我选择了不同的解决方案。我决定制作一个通用压缩器,可以在任何需要 byte[] 压缩的地方使用。您需要做更多的工作,因为您要从流中读取和写入两次,并且优化留给读者作为练习,但一般压缩完全是一个非常优雅的解决方案。

这是 GZip 的一个:

public class GZipCompressor : ICompressor
{
    public async Task<byte[]> CompressAsync(byte[] data, CancellationToken cancellationToken = default)
    {
        using var uncompressedStream = new MemoryStream(data);
        using var compressedStream = new MemoryStream();
        using (var compressorStream = new GZipStream(compressedStream, CompressionMode.Compress))
        {
            await uncompressedStream.CopyToAsync(compressorStream, cancellationToken);
        }

        return compressedStream.ToArray();
    }

    public async Task<byte[]> DecompressAsync(byte[] compressedData, CancellationToken cancellationToken = default)
    {
        using var compressedStream = new MemoryStream(compressedData);
        using var decompressorStream = new GZipStream(compressedStream, CompressionMode.Decompress);
        using var decompressedStream = new MemoryStream();
        await decompressorStream.CopyToAsync(decompressedStream, cancellationToken);

        return decompressedStream.ToArray();
    }
}

这是 Deflate 的一个:

public class DeflateCompressor: ICompressor
{
    public async Task<byte[]> CompressAsync(byte[] data, CancellationToken cancellationToken = default)
    {
        using var uncompressedStream = new MemoryStream(data);
        using var compressedStream = new MemoryStream();
        using (var compressorStream = new DeflateStream(compressedStream, CompressionMode.Compress))
        {
            await uncompressedStream.CopyToAsync(compressorStream, cancellationToken);
        }

        return compressedStream.ToArray();
    }

    public async Task<byte[]> DecompressAsync(byte[] compressedData, CancellationToken cancellationToken = default)
    {
        using var compressedStream = new MemoryStream(compressedData);
        using var decompressorStream = new DeflateStream(compressedStream, CompressionMode.Decompress);
        using var decompressedStream = new MemoryStream();
        await decompressorStream.CopyToAsync(decompressedStream, cancellationToken);

        return decompressedStream.ToArray();
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.