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

C#如何实现向MemoryStream写入指定长度比特位的WriteBits方法

C# 比特位写入MemoryStream实现方案

要实现比特级打包写入MemoryStream,首先需要明确:MemoryStream本身只支持字节为单位的写入操作,因此需要额外维护两个状态,用来暂存未写满的字节和填充进度。


完整实现代码

上下文需要的成员定义

private readonly MemoryStream _ms = new MemoryStream();
// 当前正在填充的未完成字节缓存
private byte _currentByte;
// 当前字节已填充的比特数(取值范围0-7)
private int _bitOffset;
// 预定义掩码:_bitMask[n] 代表n个比特位的全1掩码,n范围1-8
private static readonly int[] _bitMask = { 0, 0b1, 0b11, 0b111, 0b1111, 0b11111, 0b111111, 0b1111111, 0b11111111 };

WriteBits核心方法

void WriteBits(int numBits, int value)
{
    // 参数合法性校验
    if (numBits < 1 || numBits > 32)
        throw new ArgumentOutOfRangeException(nameof(numBits), "比特位长度需在1-32之间");
    if (value < 0)
        throw new ArgumentOutOfRangeException(nameof(value), "当前实现暂不支持写入负数");
    // 提前截断超出指定比特位长度的无效数值部分
    if(numBits <= 8) value &= _bitMask[numBits];

    while (numBits > 0)
    {
        int remainingBitsInCurrentByte = 8 - _bitOffset;
        int takeBits = Math.Min(numBits, remainingBitsInCurrentByte);

        // 取出本次要写入的比特段,移动到当前字节对应的位置
        int writePart = (value & (_bitMask[takeBits] << (numBits - takeBits))) >> (numBits - takeBits);
        _currentByte = (byte)(_currentByte | (writePart << (remainingBitsInCurrentByte - takeBits)));

        // 更新计数状态
        numBits -= takeBits;
        _bitOffset += takeBits;

        // 当前字节已填充满,写入流并重置临时状态
        if (_bitOffset == 8)
        {
            _ms.WriteByte(_currentByte);
            _currentByte = 0;
            _bitOffset = 0;
        }
    }
}

收尾Flush方法

所有比特写入完成后需要调用该方法,将最后未写满的字节补0后写入流:

void FlushBits()
{
    if (_bitOffset > 0)
    {
        _ms.WriteByte(_currentByte);
        _currentByte = 0;
        _bitOffset = 0;
    }
}

使用示例

和你提供的代码框架完全兼容:

// 先写入5个值为1的字节
_ms.WriteByte(1);
_ms.WriteByte(1);
_ms.WriteByte(1);
_ms.WriteByte(1);
_ms.WriteByte(1);

WriteBits(2, 3); // 写入2比特,值为3(二进制11)
WriteBits(1, 1); // 写入1比特,值为1

// 所有写入完成后执行收尾
FlushBits();

逻辑说明

该实现和你提供的Java参考实现逻辑完全对齐,核心思路都是分批次将长比特值拆分写入多个字节,暂存未写满的部分等待后续填充,避免空间浪费,完全满足网络传输场景下的比特打包性能要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:15:04