【问题标题】:BinaryReader - Reading a Single " BIT "?BinaryReader - 读取单个“BIT”?
【发布时间】:2012-03-16 09:08:57
【问题描述】:

案例:
再次尝试通过我的 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 Documentation
它将流位置提前 1 BYTE 而不是 1 BIT !!!

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

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

问候,

【问题讨论】:

    标签: c# bitarray binaryreader binarystream


    【解决方案1】:

    不,流定位基于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;
        }
    }
    

    【讨论】:

    • 那么,位排序呢? LSB 还是 MSB 在前?
    • 给你,添加了 bigEndian 支持
    • 更改方法签名以返回可为空的 bool,如果流返回 EOS (-1) 方法返回 null
    【解决方案2】:

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

    【讨论】:

      【解决方案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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-13
        • 1970-01-01
        • 1970-01-01
        • 2016-01-17
        • 1970-01-01
        • 2020-12-31
        • 2021-03-29
        • 1970-01-01
        相关资源
        最近更新 更多