4

案例:
再次尝试通过我的 NIC 捕获数据包,
我开发了 2 个扩展用于捕获可变位数

    public static string ReadBits ( this BinaryReader Key , int Value )
    {
        BitArray _BitArray = new BitArray ( Value );

        for ( int Loop = 0 ; Loop > Value ; Loop++ )
        {
/* Problem HERE ---> */   _BitArray [ Loop ] = Key . ReadBoolean ( );
        }

        return BitConverter . ToString ( _BitArray . ToByteArray ( ) );
    }

    public static byte [ ] ToByteArray ( this BitArray Key )
    {
        byte [ ] Value = new byte [ ( int ) Math . Ceiling ( ( double ) Key . Length / 8 ) ];
        Key . CopyTo ( Value , 0 );
        return Value;
    }

问题 :

_BitArray [ Loop ] = Key . ReadBoolean ( );  

当我试图读取单个位时,但参考MSDN 文档
它将流位置提前 1 BYTE 而不是 1 BIT !!!

从当前流中读取一个布尔值并将流的当前位置前移一个字节

问题:
我真的可以“仅”捕获 1 位并将流位置提前 1 位吗?
请给我建议解决方案或想法:)

问候,

4

3 回答 3

7

不,流定位是基于byte步骤的。您可以使用位定位编写自己的流实现。

class BitReader
{
    int _bit;
    byte _currentByte;
    Stream _stream;
    public BitReader(Stream stream)
    { _stream = stream; }

    public bool? ReadBit(bool bigEndian = false)
    {
      if (_bit == 8 ) 
      {

        var r = _stream.ReadByte();
        if (r== -1) return null;
        _bit = 0; 
        _currentByte  = (byte)r;
      }
      bool value;
      if (!bigEndian)
         value = (_currentByte & (1 << _bit)) > 0;
      else
         value = (_currentByte & (1 << (7-_bit))) > 0;

      _bit++;
      return value;
    }
}
于 2012-02-26T18:23:35.270 回答
3

不,不可能将Stream实例推进一位。该Stream类型支持的最小粒度是一byte

您可以编写一个包装器Stream,通过操纵和缓存一字节移动来提供一位粒度。

class BitStream { 
  private Stream _stream;
  private byte _current;
  private int _index = 8;


  public byte ReadBit() {
    if (_index >= 8) {
      _current = _stream.ReadByte();
      _index = 0;
    }
    return (_current >> _index++) & 0x1;
  }
}

注意:这会将右侧的字节读入位。如果您想从左侧阅读,则需要稍微更改一下return

于 2012-02-26T18:27:04.193 回答
1

读取 1 个字节并使用位掩码将其转换为 8 元素布尔数组

于 2012-02-26T18:24:06.693 回答