使用Deflate算法解压缩Span <byte>中的数据

Luk*_*brt 2 c# .net-core c#-7.2

我有一个解析二进制文件的代码。它用于Span<byte>在函数之间传递数据块,以避免不必要的内存分配。

简化示例:

class Reader {
    bool IsCompressed { get; set; }
    public byte[] Data { get; set; }

    function ReadOnlySpan<byte> ReadBlock() {
        ...
    }

    public function Read() {
        if (IsCompressed) {
            Data = ???
        } else {
             Data = ReadBlock.ToArray();
        }
}
Run Code Online (Sandbox Code Playgroud)

我可以使用解压缩数据Syste.IO.Compression.DeflateStream,但是此类仅接受Stream作为输入,因此我必须转换ReadOnlySpan<byte>为流,从而为分配内存byte[]

using(var stream = new MemoryStream(buffer.ToArray())) {
    using(var deflateStream = new DeflateStream(stream, CompressionMode.Decompress)) {
        Data = ... read from deflateStream
    }
}
Run Code Online (Sandbox Code Playgroud)

有什么方法可以传递ReadOnlySpan<byte>DeflateStream而不分配不必要的内存吗?还是有其他可以直接从中解压缩数据的库ReadOnlySpan<byte>

我正在使用.NET Core 2.1.0-preview1-26103-03,但如有必要,我可以使用任何其他版本。

Luk*_*brt 6

截至2018年1月,尚无对的内置支持ReadOnlySpan<byte>,但正如Stephen Toub在GitHub上指出的那样,可以使用UnmanagedMemoryStream

private unsafe byte[] Decompress(ReadOnlySpan<byte> buffer, int decompressedSize) {
    fixed (byte* pBuffer = &buffer[0]) {
        using (var stream = new UnmanagedMemoryStream(pBuffer, buffer.Length)) {
            using (var deflateStream = new DeflateStream(stream, CompressionMode.Decompress)) {
                var data = ArrayPool<byte>.Shared.Rent(decompressedSize);
                deflateStream.Read(data, 0, decompressedSize);

                return data;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)