BinaryReader ReadString指定长度?

时间:2013-10-31 15:32:30

标签: c# binaryreader

我正在研究解析器以接收UDP信息,解析它并存储它。为此,我使用的是BinaryReader,因为它主要是二进制信息。其中一些将是字符串。 ReadString()函数的MSDN says

  

从当前流中读取字符串。字符串以前缀为前缀   长度,一次编码为整数7位。

我完全理解它,直到“一次七位”,我试图忽略,直到我开始测试。我在创建自己的字节数组之前将其放入MemoryStream并尝试使用BinaryReader进行读取。这是我最初认为可行的方法:

byte[] data = new byte[] { 3, 0, 0, 0, (byte)'C', (byte)'a', (byte)'t', }
BinaryReader reader = new BinaryReader(new MemoryStream(data));
String str = reader.ReadString();

知道一个int是4个字节(并且足够长的时间来发现BinaryReader是Little Endian)我将它的长度传递给3和相应的字母。但是str最终会占据\0\0\0。如果我删除3个零并且只有

byte[] data = new byte[] { 3, (byte)'C', (byte)'a', (byte)'t', }

然后它正确地读取和存储Cat。对我来说,这与文档冲突说长度应该是一个整数。现在我开始认为它们只是指一个没有小数位且不是数据类型int的数字。这是否意味着BinaryReader永远不会读取大于127个字符的字符串(因为这将是对应于文档的7位部分的01111111)?

我正在编写一个协议,需要在将文档传递给客户之前完全理解我正在进行的工作。

2 个答案:

答案 0 :(得分:6)

我找到BinaryReader的{​​{3}}。它使用了一个名为source code的函数,在查找了Read7BitEncodedInt()的文档和文档后,我发现了这个:

  

值参数的整数在a处写出7位   时间,从七个最低有效位开始。高位   一个字节表示此后是否有更多字节要写入   一。如果value适合7位,则只需要一个字节的空间。   如果值不适合7位,则在第1位设置高位   字节并写出来。然后将值移位7位,然后移位   字节写入。重复此过程,直到整数整数为止   写了。

此外,拉尔夫发现Write7BitEncodedInt()可以更好地显示正在发生的事情。

答案 1 :(得分:0)

除非他们专门说'int'或'Int32',否则它们只是表示整数。

“一次7位”表示它们实现7位长度的编码,乍一看似乎有些混乱,但实际上相当简单。以下是一些示例值,以及如何使用7位长度编码将其写出:

/*
decimal value   binary value                ->  enc byte 1   enc byte 2   enc byte 3
85              00000000 00000000 01010101  ->  01010101     n/a          n/a
1,365           00000000 00000101 01010101  ->  11010101     00001010     n/a
349,525         00000101 01010101 01010101  ->  11010101     10101010     00010101
*/

上面的表使用大字节序,除了我只需要选择一个,这就是我最熟悉的原因。 7位长度编码的工作方式,就其本质而言,它几乎没有尾数。

请注意,85写入1字节,1,365写入2字节,349,525写入3字节。

在同一张表中使用字母显示写入输出中每个值的位是如何使用的(破折号是零值位,而0和1是编码机制添加的值,以指示是否要使用后续字节书面/阅读)...

/*
decimal value   binary value                ->  enc byte 1   enc byte 2   enc byte 3
85              -------- -------- -AAAAAAA  ->  0AAAAAAA     n/a          n/a
1,365           -------- -----BBB AAAAAAAA  ->  1AAAAAAA     0---BBBA     n/a
349,525         -----CCC BBBBBBBB AAAAAAAA  ->  1AAAAAAA     1BBBBBBA     0--CCCBB
*/

因此,0到2 ^ 7-1(127)范围内的值将写为1个字节,2 ^ 7(128)到2 ^ 14-1(16,383)范围内的值将使用2个字节,即2 ^ 14(16,384)到2 ^ 21-1(2,097,151)将占用3个字节,依此类推。