You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# .NET如何基于大文件流指定片段创建GZipStream降低内存占用

实现方案

你不需要把目标压缩段全部加载到内存,只需要通过自定义的长度限制包装流封装FileStream即可实现流式读取解压:


步骤1:实现长度限制的包装流

这个流的作用是包装原始FileStream,限制最多只能读取指定长度的字节,避免GZipStream读取到超出目标压缩段的内容:

public class BoundedReadStream : Stream
{
    private readonly Stream _innerStream;
    private long _remainingBytes;

    public BoundedReadStream(Stream innerStream, long maxReadLength)
    {
        _innerStream = innerStream ?? throw new ArgumentNullException(nameof(innerStream));
        _remainingBytes = maxReadLength;
        if (!innerStream.CanRead) throw new ArgumentException("传入的流必须支持读取", nameof(innerStream));
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        if (_remainingBytes <= 0) return 0;
        var bytesToRead = (int)Math.Min(count, _remainingBytes);
        var bytesRead = _innerStream.Read(buffer, offset, bytesToRead);
        _remainingBytes -= bytesRead;
        return bytesRead;
    }

    // 以下属性和方法按需实现,GZipStream仅依赖读相关的核心实现
    public override bool CanRead => true;
    public override bool CanSeek => false;
    public override bool CanWrite => false;
    public override long Length => throw new NotSupportedException();
    public override long Position { get => throw new NotSupportedException(); set => throw new NotSupportedException(); }
    public override void Flush() => throw new NotSupportedException();
    public override long Seek(long offset, SeekOrigin origin) => throw new NotSupportedException();
    public override void SetLength(long value) => throw new NotSupportedException();
    public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
}

步骤2:调整解压逻辑

直接操作FileStream,不需要中间转存MemoryStream:

// 打开文件流
using FileStream fileStream = new FileStream("你的文件路径", FileMode.Open, FileAccess.Read);
// 定位到压缩数据的起始地址
fileStream.Position = 你要的压缩数据起始地址;
// 用长度限制流包装,只允许读取指定长度的压缩数据
using BoundedReadStream boundedStream = new BoundedReadStream(fileStream, 你要的压缩数据长度);
// 直接传入GZipStream解压
using GZipStream gZipStream = new GZipStream(boundedStream, CompressionMode.Decompress);

// 后续直接从gZipStream流式读取解压后的数据即可,全程不会加载全量压缩数据到内存
// 示例:把解压后的数据写入到目标文件
// using var outputFs = File.Create("解压后输出路径");
// gZipStream.CopyTo(outputFs);

注意事项

  • 请确保你指定的起始地址到结束地址之间的内容是完整的GZip格式压缩数据,否则会抛出解压异常
  • 该方案内存占用仅为读写缓冲区默认大小(通常是4KB),适合处理GB级以上的大容量压缩段

内容的提问来源于stack exchange,提问作者S41L0R

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 02:54:00